copy vs. uninitialized_copy

本文探讨了STL中copy与uninitialized_copy函数的区别。copy适用于已初始化的目标区域,并通过调用赋值运算符实现复制;而uninitialized_copy则用于未初始化的目标区域,通过调用拷贝构造函数来完成复制过程。

copy 是依次调用重载的运算符=,

uninitialized_copy是依次调用拷贝构造函数


如果目标区间是未初始化的,应该用uninitialized_copy, 否则用copy

在标头 <memory> 定义 uninitialized_copy 复制范围中对象到未初始化内存 (函数模板) ranges::uninitialized_copy (C++20) 复制范围中对象到未初始化内存 (算法函数对象) uninitialized_copy_n (C++11) 复制若干对象到未初始化内存 (函数模板) ranges::uninitialized_copy_n (C++20) 复制若干对象到未初始化内存 (算法函数对象) uninitialized_fill 复制一个对象到范围所定义的未初始化内存 (函数模板) ranges::uninitialized_fill (C++20) 复制一个对象到范围所定义的未初始化内存 (算法函数对象) uninitialized_fill_n 复制一个对象到起点和数量所定义的未初始化内存 (函数模板) ranges::uninitialized_fill_n (C++20) 复制一个对象到起点和数量所定义的未初始化内存 (算法函数对象) uninitialized_move (C++17) 移动范围中对象到未初始化内存 (函数模板) ranges::uninitialized_move (C++20) 移动范围中对象到未初始化内存 (算法函数对象) uninitialized_move_n (C++17) 移动若干对象到未初始化内存 (函数模板) ranges::uninitialized_move_n (C++20) 移动若干对象到未初始化内存 (算法函数对象) uninitialized_default_construct (C++17) 在范围所定义的未初始化内存中用默认初始化构造对象 (函数模板) ranges::uninitialized_default_construct (C++20) 在范围所定义的未初始化内存中用默认初始化构造对象 (算法函数对象) uninitialized_default_construct_n (C++17) 在起点和数量所定义的未初始化内存中用默认初始化构造对象 (函数模板) ranges::uninitialized_default_construct_n (C++20) 在起点和数量所定义的未初始化内存中用默认初始化构造对象 (算法函数对象) uniniti
05-02
#include "data_changes.h" #include "ras_common.h" extern PIRSensor_p sensor; extern g4_module_ctx_t* g_ctx_air780; global_state_t g_state = { .ina219 = NULL, .dht11_pin = 21, .restart_gpio = 12, .current_lat = 0.0f, .current_lng = 0.0f, .has_valid_gps = 0, .last_th = -1000.0f, .last_rh = -1000.0f, .last_percent = -1000.0f, .last_reported_percent = -1000.0f, .last_lat_for_dist = 0.0f, .last_lng_for_dist = 0.0f, .last_csq_rssi = -1, .first_sample_done = 0, .keep_running = 1, .data_thread_running = 0, .data_thread = 0, .restart_thread = 0 }; // Thing_Model_t g_thing_Model; void stop_all_threads(void); // 同步 module info 的互斥锁 extern pthread_mutex_t g_module_info_mutex; // ==================== GPS 回调 ==================== void my_gps_data_handle(const gps_paresd_data_t* data) { if (!data || data->lat[0] == '\0' || data->lng[0] == '\0') return; //printf("纬度: %s, 经度: %s\n", data->lat, data->lng); float lat_raw = atof(data->lat); float lng_raw = atof(data->lng); if (lat_raw != 0.0f && lng_raw != 0.0f) { // 转换 DDMM.MMMM 格式到 DD.DDDDDD 十进制度数 float lat_deg = floorf(lat_raw / 100.0f); float lat_min = lat_raw - lat_deg * 100.0f; g_state.current_lat = lat_deg + lat_min / 60.0f; float lng_deg = floorf(lng_raw / 100.0f); float lng_min = lng_raw - lng_deg * 100.0f; g_state.current_lng = lng_deg + lng_min / 60.0f; g_state.has_valid_gps = 1; // 生成百度坐标字符串 zuobiao_dta(lng_raw, lat_raw, g_state.buf_lat_lng, sizeof(g_state.buf_lat_lng)); printf("转换后坐标: %s (WGS84: %.6f, %.6f)\n", g_state.buf_lat_lng, g_state.current_lng, g_state.current_lat); writeFilegps(g_state.buf_lat_lng, "zuobiao.txt"); } else { // printf("GPS 数据无效(0.0)\n"); // printf("经纬度:%s\n",g_state.buf_lat_lng); } } // ==================== 重新初始化硬件 ==================== int reinitialize_hardware(void) { printf("重新初始化硬件...\n"); // 重新初始化 INA219 if (g_state.ina219) { ina219_close(g_state.ina219); } g_state.ina219 = start_init_in291(); if (!g_state.ina219) { fprintf(stderr, "[ERROR] INA219 重新初始化失败\n"); return -1; } // 重新初始化 DHT11 if (!dht11_init(g_state.dht11_pin)) { fprintf(stderr, "[ERROR] DHT11 重新初始化失败\n"); return -1; } // 重新初始化 GPIO if (qckg_init(g_state.restart_gpio) != 0) { fprintf(stderr, "[ERROR] GPIO 重新初始化失败\n"); return -1; } // 重新初始化 4G 模块 g4_module_config_t config = { .serial_device = "/dev/ttyAMA0", .baud_rate = 9600, .timeout_seconds = 3, .max_retry = 3 }; if (start_air780_debug(config) == 0) { fprintf(stderr, "[ERROR] 4G 模块重新启动成功\n"); // 重置状态变量 g_state.last_th = -1000.0f; g_state.last_rh = -1000.0f; g_state.last_percent = -1000.0f; g_state.last_reported_percent = -1000.0f; g_state.last_csq_rssi = -1; //清空GPS全局变量 memset(g_state.buf_lat_lng, 0, sizeof(g_state.buf_lat_lng)); g_state.current_lat = 0.0f; g_state.current_lng = 0.0f; g_state.has_valid_gps = 0; printf("重新初始化GPS模块...\n"); set_gps_data_callback(my_gps_data_handle); sleep(1); // 等待旧线程退出 gps_data_init_with_device("/dev/ttyAMA1"); // 重置状态变量 g_state.first_sample_done = 0; printf("硬件重新初始化成功\n"); return 0; } return 0; } // ==================== 信号处理函数 ==================== void signal_handler(int sig) { printf("\n接收到信号 %d,准备退出...\n", sig); g_state.keep_running = 0; } // ==================== 数据采集线程 ==================== void* pthread_data_change(void* arg) { printf("数据采集线程启动\n"); // 等待完成,设置超时时间 int timeout = 300; // 超时 int wait_count = 0; while (g_ctx_air780->current_step != STEP_COMPLETE) { sleep(1); // 等待1秒 wait_count++; if (wait_count >= timeout) { printf("等待超时,当前步骤: %d\n", g_ctx_air780->current_step); break; } } //等待温湿度数据读取成功 int temp_humid_timeout = 360; // 温湿度读取超时时间(秒) int temp_humid_wait_count = 0; int temp_humid_valid = 0; printf("等待温湿度传感器数据...\n"); while (!temp_humid_valid && temp_humid_wait_count < temp_humid_timeout) { // 尝试读取温湿度数据 DHT11_Data_t d = dht11_read_data(g_state.dht11_pin); if (d.humidity_integer != 0 || d.temperature_integer != 0) { float current_rh = (float)d.humidity_integer + (float)d.humidity_decimal / 10.0f; float current_th = (float)d.temperature_integer + (float)d.temperature_decimal / 10.0f; if (current_th > -40.0f && current_th < 80.0f && current_rh >= 0.0f && current_rh <= 100.0f) { printf("成功读取温湿度: 温度%.1f℃, 湿度%.1f%%\n", current_th, current_rh); temp_humid_valid = 1; break; } } temp_humid_wait_count++; if (temp_humid_wait_count % 5 == 0) { printf("等待温湿度数据... (%d/%d 秒)\n", temp_humid_wait_count, temp_humid_timeout); } sleep(1); } if (!temp_humid_valid) { printf("警告: 温湿度读取异常,继续执行...\n"); } if (g_ctx_air780->current_step == STEP_COMPLETE) { // printf("步骤完成,继续执行...\n"); // if(get_ip_address(g_state.reportInfo_Device_Status.ipAddress,sizeof(g_state.reportInfo_Device_Status.ipAddress)) // &&get_rpi_serial(g_state.reportInfo_Device_Status.deviceSN, sizeof(g_state.reportInfo_Device_Status.deviceSN)) // &&get_device_model(g_state.reportInfo_Device_Status.deviceModel,sizeof(g_state.reportInfo_Device_Status.deviceModel)) // &&get_firmware_version(g_state.reportInfo_Device_Status.firmwareVersion, sizeof(g_state.reportInfo_Device_Status.firmwareVersion)) // &&get_hardware_nrevisio(g_state.reportInfo_Device_Status.hardwareVersion, sizeof(g_state.reportInfo_Device_Status.hardwareVersion))) // { // printf("设备信息获取成功\n"); // memcpy(g_state.reportInfo_Device_Status.sdCardStatus,"正常",sizeof(g_state.reportInfo_Device_Status.sdCardStatus)); // if(sensor != NULL) // { // g_state.reportInfo_Device_Status.motionDetectEnable = 1; // }else{ // g_state.reportInfo_Device_Status.motionDetectEnable = 0; // } // vp_reportinfo_Device_Status(&g_state.reportInfo_Device_Status); // } } else { printf("步骤未完成,当前状态: %d\n", g_ctx_air780->current_step); } while ((g_state.data_thread_running)&&(g_ctx_air780->current_step == STEP_COMPLETE)) { sleep(10); // 1. 网络路由 char out_route[32] = {0}; route_select(out_route, sizeof(out_route)); // 2. 电量 float bus_voltage = -1.0f; if (g_state.ina219) { bus_voltage = ina219_get_bus_voltage_V(g_state.ina219); } float current_percent = (bus_voltage - 6.0f) / 2.17f * 100.0f; current_percent = fmaxf(0.0f, fminf(100.0f, current_percent)); printf("当前电量%.1f\n",current_percent); // 3. 温湿度 DHT11_Data_t d = dht11_read_data(g_state.dht11_pin); float current_th = -1.0f, current_rh = -1.0f; if (d.humidity_integer != 0 || d.temperature_integer != 0) { current_rh = (float)d.humidity_integer + (float)d.humidity_decimal / 10.0f; current_th = (float)d.temperature_integer + (float)d.temperature_decimal / 10.0f; printf("温度%.1f, 湿度%.1f\n", current_th, current_rh); } // 4. 网络状态 + CSQ 解析 int current_csq_rssi = update_network_info(out_route); update_device_info(); // 5. 判断是否需要上报 int should_report_1 = 0; int should_report_2 = 0; int should_report_3 = 0; // 路由变化检测 if (strcmp(out_route, g_state.last_route_show) != 0) { should_report_3 = 1; printf("路由变化: %s -> %s,触发上报\n", g_state.last_route_show, out_route); memset(g_state.last_route_show, 0, sizeof(g_state.last_route_show)); size_t route_len = strlen(out_route); size_t copy_len = (route_len < sizeof(g_state.last_route_show)) ? route_len : (sizeof(g_state.last_route_show) - 1); memcpy(g_state.last_route_show, out_route, copy_len); } if (g_state.has_valid_gps && g_state.first_sample_done) { if (g_state.last_lat_for_dist == 0.0f && g_state.last_lng_for_dist == 0.0f) { g_state.last_lat_for_dist = g_state.current_lat; g_state.last_lng_for_dist = g_state.current_lng; printf("[DEBUG] 初始化参考坐标: lat=%.6f, lng=%.6f\n", g_state.last_lat_for_dist, g_state.last_lng_for_dist); } printf("[DEBUG] 距离计算: 上次(%.6f, %.6f) -> 当前(%.6f, %.6f)\n", g_state.last_lat_for_dist, g_state.last_lng_for_dist, g_state.current_lat, g_state.current_lng); float dist = haversine_distance_m( g_state.last_lat_for_dist, g_state.last_lng_for_dist, g_state.current_lat, g_state.current_lng ); printf("[DEBUG] 计算距离: %.2f 米\n", dist); if (dist > 40.0f) { should_report_1 = 1; printf("[DEBUG] 更新参考坐标: lat=%.6f, lng=%.6f\n", g_state.current_lat, g_state.current_lng); g_state.last_lat_for_dist = g_state.current_lat; g_state.last_lng_for_dist = g_state.current_lng; SAFE_MEMCPY(g_state.lng_lat, g_state.buf_lat_lng, sizeof(g_state.lng_lat)); printf("位置变化 %.1f 米,触发上报\n", dist); } } //温湿度变化检测 if (current_th >= 0 && g_state.last_th >= 0 && fabsf(current_th - g_state.last_th) > 2.0f) { should_report_2 = 1; printf("温度变化 %.1f℃,触发上报\n", fabsf(current_th - g_state.last_th)); } if (current_rh >= 0 && g_state.last_rh >= 0 && fabsf(current_rh - g_state.last_rh) > 3.0f) { should_report_2 = 1; printf("湿度变化 %.1f%%,触发上报\n", fabsf(current_rh - g_state.last_rh)); } // 电量累计变化检测 if (g_state.last_reported_percent >= 0) { float accumulated_change = fabsf(current_percent - g_state.last_reported_percent); if (accumulated_change >= 1.0f) { should_report_2 = 1; g_state.last_reported_percent = current_percent; printf("电量累计变化 %.1f%%,触发上报\n", accumulated_change); } } // 保存旧值 int old_csq = g_state.last_csq_rssi; // 更新 g_state.last_csq_rssi if (current_csq_rssi >= 0) { g_state.last_csq_rssi = current_csq_rssi; } // 判断是否需要上报 if (current_csq_rssi >= 0) { if (old_csq == -1) { // 首次有效值,触发上报 should_report_3 = 1; printf("首次获取有效 CSQ: %d,触发上报\n", current_csq_rssi); } else if (abs(current_csq_rssi - old_csq) > 6) { should_report_3 = 1; printf("CSQ 变化 %d -> %d,触发上报\n", old_csq, current_csq_rssi); } } // 首次采集 if (!g_state.first_sample_done) { printf("首次采集上报\n"); should_report_2 = 1; should_report_1 = 1; should_report_3 = 1; g_state.first_sample_done = 1; g_state.last_reported_percent = current_percent; if (g_state.has_valid_gps) { should_report_1 = 1; g_state.last_lat_for_dist = g_state.current_lat; g_state.last_lng_for_dist = g_state.current_lng; SAFE_MEMCPY(g_state.lng_lat, g_state.buf_lat_lng, sizeof(g_state.lng_lat)); } if (current_csq_rssi >= 0) { g_state.last_csq_rssi = current_csq_rssi; } memset(g_state.last_route_show, 0, sizeof(g_state.last_route_show)); size_t route_len = strlen(out_route); size_t copy_len = (route_len < sizeof(g_state.last_route_show)) ? route_len : (sizeof(g_state.last_route_show) - 1); memcpy(g_state.last_route_show, out_route, copy_len); printf("首次采集,上报\n"); } else { if (current_csq_rssi >= 0) { g_state.last_csq_rssi = current_csq_rssi; } } // 更新其他"上次值" g_state.last_percent = current_percent; if(current_th >= 0) { // 更新结构体 g_state.reportInfo_Location_Power_TemperatureHumidity.th = (current_th < 0) ? -1.0f : roundf(current_th * 100.0f) / 100.0f; g_state.reportInfo_Location_Power_TemperatureHumidity.rh = current_rh; } snprintf(g_state.reportInfo_Location_Power_TemperatureHumidity.percent, sizeof(g_state.reportInfo_Location_Power_TemperatureHumidity.percent), "%.1f", current_percent); // 6. 执行上报 vp_reportInfo_Information(&g_state.reportInfo_Information); usleep(1000000); if (should_report_2&&g_state.reportInfo_Location_Power_TemperatureHumidity.th >= 0&&g_state.reportInfo_Location_Power_TemperatureHumidity.rh >= 0) { vp_reportInfo_Power_TemperatureHumidity(&g_state.reportInfo_Location_Power_TemperatureHumidity); // 上报后更新温湿度和电量的上报基准值 if (current_th >= 0) g_state.last_th = current_th; if (current_rh >= 0) g_state.last_rh = current_rh; g_state.last_reported_percent = current_percent; usleep(1000000); } if (should_report_3) { vp_reportInfo_Network_Status(&g_state.reportInfo_Network_Status); usleep(1000000); } if(should_report_1){ vp_reportInfo_Location(g_state.lng_lat); usleep(1000000); } } cleanup_resources(); printf("数据采集线程退出\n"); return NULL; } // ==================== 重启检测线程 ==================== void* pthread_data_restart(void* arg) { int gpio_pin = (int)(intptr_t)arg; time_t start_time = 0; int high_detected = 0; time_t last_restart_time = 0; // 上次重启时间 const int RESTART_COOLDOWN = 10; // 重启冷却时间(秒) printf("重启检测线程启动,监控GPIO%d\n", gpio_pin); while (g_state.keep_running) { int state = qckg_read(gpio_pin); if (state == 1) { if (!high_detected) { start_time = time(NULL); high_detected = 1; printf("检测到高电平,开始计时...\n"); } else { if (difftime(time(NULL), start_time) >= 3.0) { time_t current_time = time(NULL); // 检查冷却时间 if (difftime(current_time, last_restart_time) < RESTART_COOLDOWN) { printf("重启操作过于频繁(冷却时间剩余: %.0f秒)\n", RESTART_COOLDOWN - difftime(current_time, last_restart_time)); high_detected = 0; start_time = 0; continue; } printf("高电平持续3秒,触发硬件重新初始化\n"); last_restart_time = current_time; // 清理资源 stop_all_threads(); printf("等待硬件稳定...\n"); sleep(2); if (reinitialize_hardware() == 0) { memset(&g_state.reportInfo_Information, 0, sizeof(g_state.reportInfo_Information)); memset(&g_state.reportInfo_Network_Status, 0, sizeof(g_state.reportInfo_Network_Status)); memset(&g_state.reportInfo_Location_Power_TemperatureHumidity, 0, sizeof(g_state.reportInfo_Location_Power_TemperatureHumidity)); memset(&g_state.reportInfo_Device_Status, 0, sizeof(g_state.reportInfo_Device_Status)); printf("硬件重新初始化成功\n"); // 重新启动数据采集线程 g_state.data_thread_running = 1; if (pthread_create(&g_state.data_thread, NULL, pthread_data_change, NULL) != 0) { fprintf(stderr, "重新创建数据采集线程失败\n"); g_state.data_thread_running = 0; } else { printf("数据采集线程重新启动成功\n"); } } else { fprintf(stderr, "硬件重新初始化失败\n"); } // 重置检测状态 high_detected = 0; start_time = 0; } } } else { if (high_detected) { printf("高电平中断,重置计时\n"); high_detected = 0; start_time = 0; } } usleep(100000); // 100ms } printf("重启检测线程退出\n"); return NULL; } // ==================== 外部接口 ==================== int data_change() { if (g_state.data_thread != 0) { printf("数据采集线程已在运行\n"); return 0; } // 初始化硬件 // wiring_init(); // g_state.dht11_pin = 21; // g_state.restart_gpio = 17; // 初始化硬件 if (reinitialize_hardware() == 0) { g_state.data_thread_running=1; int ret = pthread_create(&g_state.data_thread, NULL, pthread_data_change, NULL); if (ret != 0) { fprintf(stderr, "创建数据采集线程失败: %d\n", ret); g_state.data_thread_running = 0; return -1; } }else { printf("初始化硬件失败\n"); } printf("数据采集启动成功\n"); return 0; } int restart() { if (g_state.restart_thread != 0) { printf("重启检测线程已在运行\n"); return 0; } // const int gpio_pin = 17; int ret = pthread_create(&g_state.restart_thread, NULL, pthread_data_restart, (void*)(intptr_t)g_state.restart_gpio); if (ret != 0) { fprintf(stderr, "创建重启检测线程失败: %d\n", ret); return -1; } printf("重启检测启动成功\n"); return 0; } // 停止所有线程 void stop_all_threads(void) { printf("停止所有线程...\n"); g_state.data_thread_running = 0; if (g_state.data_thread) { pthread_join(g_state.data_thread, NULL); g_state.data_thread = 0; } cleanup_resources(); printf("所有线程已停止\n"); } 这个是相关代码
最新发布
11-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值