You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:40:28