Visual Studio x64编译下函数未按预期返回字节数组问题
Visual Studio x64编译返回字节数组出现乱码问题
问题详情
代码在在线编译器可正常输出预期的8字节数组 BB-CC-C3-02-5C-11-6D-00,但Visual Studio 2022 x64编译后输出大量乱码;x86编译可正常运行,但因需求必须使用x64编译,需明确问题原因及修复方法。
问题代码
/*******************************************************************************/ #include <stdio.h> #include <stdint.h> uint8_t * createByteArray(float power, int power_coefficient); int main() { float power = 4444; int power_coefficient = 1; uint8_t * returned_ptr = createByteArray(power, power_coefficient); for (int i = 0; i < returned_ptr[3]+6; i++) printf("%02X-", returned_ptr[i]); return 0; } uint8_t * createByteArray(float power, int power_coefficient) { uint16_t power_ushort = (uint16_t)(power * power_coefficient); uint8_t bytes_power[2]; bytes_power[0] = (uint8_t)((power_ushort >> 8) & 0xFF); bytes_power[1] = (uint8_t)(power_ushort & 0xFF); uint8_t firstHalf_power = bytes_power[0]; uint8_t secondHalf_power = bytes_power[1]; int parity = (int)firstHalf_power + (int)secondHalf_power; uint16_t parity_ushort = (uint16_t)(parity); uint8_t bytes_parity[2]; bytes_parity[0] = (uint8_t)((parity_ushort >> 8) & 0xFF); bytes_parity[1] = (uint8_t)(parity_ushort & 0xFF); uint8_t firstHalf_parity = bytes_parity[0]; uint8_t secondHalf_parity = bytes_parity[1]; uint8_t telegram_set_power[8] = {0xBB, 0xCC, 0xC3, 0x02, secondHalf_power, firstHalf_power, secondHalf_parity, firstHalf_parity}; uint8_t * ptr = telegram_set_power; return ptr; }
Visual Studio 2022 x64编译输出
AA-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-00-00-00-00-00-00-00-00-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-CC-A8-00-00-00-00-00-00-00-A8-00-00-00-00-00-00-00-45-64-DD-8D-FA-7F-00-00-00-00-00-00-00-00-00-00-64-00-1B-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-36-9D-EA-8D-FA-7F-00-00-A0-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-CC-F6-11-AE-2C-00-00-00-10-00-00-00-00-00-00-00-D0-F5-11-AE-2C-00-00-00-1C-00-1B-00-00-01-00-00-E0-F5-11-AE-2C-00-00-00-14-00-00-00-00-00-00-01-00-00-00-00-00-00-00-00-00-00-
问题原因
核心问题是返回栈内存指针导致的未定义行为:
createByteArray函数中的telegram_set_power是局部数组,存储在函数栈帧中。函数执行完毕后,栈帧会被销毁,这块内存会被标记为可复用,此时返回的指针指向的是无效内存。- x86编译时,栈内存可能暂时未被覆盖,所以输出正常,但这是偶然现象,并非正确行为。
- x64编译时,栈内存的回收和复用策略更激进,函数返回后原栈内存很快被其他数据覆盖,因此输出乱码。
- 在线编译器的栈内存管理策略不同,暂时保留了数据,但同样属于不可靠的未定义行为。
修复方案
方案1:使用静态数组(单线程场景可用)
将telegram_set_power声明为static,使其存储在全局数据区而非栈上:
static uint8_t telegram_set_power[8] = {0xBB, 0xCC, 0xC3, 0x02, secondHalf_power, firstHalf_power, secondHalf_parity, firstHalf_parity};
注意:静态数组是全局共享的,多线程调用该函数会覆盖数据,仅适用于单线程场景。
方案2:动态分配内存(推荐)
使用malloc在堆上分配内存,使用完毕后需调用free释放:
uint8_t * createByteArray(float power, int power_coefficient) { uint16_t power_ushort = (uint16_t)(power * power_coefficient); uint8_t bytes_power[2]; bytes_power[0] = (uint8_t)((power_ushort >> 8) & 0xFF); bytes_power[1] = (uint8_t)(power_ushort & 0xFF); uint8_t firstHalf_power = bytes_power[0]; uint8_t secondHalf_power = bytes_power[1]; int parity = (int)firstHalf_power + (int)secondHalf_power; uint16_t parity_ushort = (uint16_t)(parity); uint8_t bytes_parity[2]; bytes_parity[0] = (uint8_t)((parity_ushort >> 8) & 0xFF); bytes_parity[1] = (uint8_t)(parity_ushort & 0xFF); uint8_t firstHalf_parity = bytes_parity[0]; uint8_t secondHalf_parity = bytes_parity[1]; uint8_t *telegram_set_power = malloc(8 * sizeof(uint8_t)); if (telegram_set_power == NULL) { // 处理内存分配失败,比如返回NULL return NULL; } telegram_set_power[0] = 0xBB; telegram_set_power[1] = 0xCC; telegram_set_power[2] = 0xC3; telegram_set_power[3] = 0x02; telegram_set_power[4] = secondHalf_power; telegram_set_power[5] = firstHalf_power; telegram_set_power[6] = secondHalf_parity; telegram_set_power[7] = firstHalf_parity; return telegram_set_power; }
主函数中使用后记得释放内存:
int main() { float power = 4444; int power_coefficient = 1; uint8_t * returned_ptr = createByteArray(power, power_coefficient); if (returned_ptr != NULL) { for (int i = 0; i < returned_ptr[3]+6; i++) printf("%02X-", returned_ptr[i]); free(returned_ptr); } return 0; }
方案3:由调用者提供缓冲区(最安全)
让主函数传入缓冲区,避免内存管理问题:
void createByteArray(float power, int power_coefficient, uint8_t *output) { uint16_t power_ushort = (uint16_t)(power * power_coefficient); uint8_t bytes_power[2]; bytes_power[0] = (uint8_t)((power_ushort >> 8) & 0xFF); bytes_power[1] = (uint8_t)(power_ushort & 0xFF); uint8_t firstHalf_power = bytes_power[0]; uint8_t secondHalf_power = bytes_power[1]; int parity = (int)firstHalf_power + (int)secondHalf_power; uint16_t parity_ushort = (uint16_t)(parity); uint8_t bytes_parity[2]; bytes_parity[0] = (uint8_t)((parity_ushort >> 8) & 0xFF); bytes_parity[1] = (uint8_t)(parity_ushort & 0xFF); uint8_t firstHalf_parity = bytes_parity[0]; uint8_t secondHalf_parity = bytes_parity[1]; output[0] = 0xBB; output[1] = 0xCC; output[2] = 0xC3; output[3] = 0x02; output[4] = secondHalf_power; output[5] = firstHalf_power; output[6] = secondHalf_parity; output[7] = firstHalf_parity; }
主函数调用:
int main() { float power = 4444; int power_coefficient = 1; uint8_t buffer[8]; createByteArray(power, power_coefficient, buffer); for (int i = 0; i < buffer[3]+6; i++) printf("%02X-", buffer[i]); return 0; }
内容的提问来源于stack exchange,提问作者pnatk
相关产品推荐
相关产品推荐

