簡體   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