memcpy unsigned int 到 unsigned char 分段错误

memcpy unsigned int to unsigned char segmentation fault

我想将 4 个字节从 unsigned int 复制到 unsigned char 数组。执行以下函数后 get_result 会出现分段错误:

int exec_cmd(unsigned int * apu32Var)
{
    int  ret = -1;
    char cmd[100] = { 0 };
    char resp[100] = { 0 };

    sprintf(cmd, "%s %s", "/home/send_frames.sh", "read");
    ret = exec_cmd_ret_result(cmd, resp);

    if( apu32Var != NULL )
    {
        *apu32Var = (((unsigned int)resp[0]) <<24)+(((unsigned int)resp[1]) <<16)+(((unsigned int)resp[2]) <<8)+(unsigned int)resp[3];
    }
    return ret;
}

int get_result(unsigned char * buffer, unsigned short * size)
{
    unsigned int u32Var = 0;

    exec_cmd(&u32Var);

    memcpy(buffer, &u32Var, sizeof(unsigned int));  
    *size += sizeof(unsigned int);
    return 0;
}


int main(int argc, char **argv)
{
    unsigned char *buf;
    unsigned short *size;

    get_result(buf+4, size);

    return 0;
}

但是,关于 memcpy() 手册页,似乎 memcpy() 管理得很好。出了什么问题?

buf in main 从未初始化,因此它指向内存中的某个随机位置。这是未定义的行为,是段错误的完美配方。

类似地,当您使用 += 时会读取 *size,但该值从未在 main 中初始化,因此您取消引用未定义的值。

您应该将 buf 声明为足够大小的数组并将其传入。此外,将 size 声明为 int,将其初始化为 0,并传递其地址:

int main(int argc, char **argv)
{
    unsigned char buf[100];
    unsigned short size = 0;

    // I'm assuming this was a typo and you ment to call get_result instead of test_result
    get_result(buf, &size);

    return 0;
}

假设您对 test_result 的调用实际上应该调用 get_result,那么您有两个大问题。

第一个也是最严重的问题是您将未初始化的局部变量作为参数传递给函数。未初始化的局部变量具有 不确定 值。对于一个指针,这意味着它几乎可以指向任何地方,并且试图取消引用它会导致未定义的行为。您实际上需要使这些指针指向某个有效的地方才能使其工作。这适用于两个变量。

第二个问题是您误解了在 C 中模拟按引用传递的方式。是的,函数应该采用指针,但您实际上不应该创建指针变量并传递给函数。相反,您应该在非指针变量上使用寻址运算符 &

要解决这两个问题,您的代码应该类似于

unsigned char buf[256] = { 0 };  // Arbitrary size, all initialized to zero
unsigned short size = 0; // To make sure it's properly initialized

get_result(buf + 4, &size);  // Note use of & to pass a pointer to the variable size

请注意,它使用数组工作,因为数组自然会衰减为指向其第一个元素的指针。