繁体   English   中英

memcpy unsigned int to unsigned char segmentation fault

[英]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()管理得很好。 出了什么问题?

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

第一个也是最严重的是你将未初始化的局部变量作为函数的参数传递。 未初始化的局部变量具有不确定的值。 对于指针,它意味着它可以指向任何地方,并且尝试取消引用它将导致未定义的行为 你需要实际让这些指针指向一个有效的工作点。 这适用于两个变量。

第二个问题是你误解了模拟传递引用如何在C中工作。是的函数应该采用指针,但你不应该实际创建指针变量并传递给函数。 相反,你应该使用address-of运算符&非指针变量。

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

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

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

main buf永远不会被初始化,因此它指向内存中的一些随机位置。 这是未定义的行为,也是段错误的完美配方。

类似地, *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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM