memcpy unsigned int to unsigned char segmentation fault

时间:2016-02-15 13:09:35

标签: c linux segmentation-fault memcpy

我想将unsigned int中的4个字节复制到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()管理得很好。出了什么问题?

2 个答案:

答案 0 :(得分:2)

假设您拨打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

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

答案 1 :(得分:1)

buf中的{p> 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;
}