2014-10-17 85 views
1

我有兩種類型的struct s,struct msgstruct pkt。 我的工作是使用struct msg構建一個struct pkt作爲參數傳遞。使用strcpy拋出「stack smashing detected」錯誤

struct msg { 
    char data[20]; 
    }; 

struct pkt { 
    int seqnum; 
    int acknum; 
    int checksum; 
    char payload[20]; 
    }; 

雖然

void A_output(struct msg message) { //fails 
    ... 
    struct pkt snd_pkt; 
    strcpy(snd_pkt.payload, message.data); 
    ... 
} 

失敗,

void A_output(struct msg message) { //succeeds 
    ... 
    struct pkt snd_pkt; 
    memcpy(&snd_pkt.payload, &message, sizeof(struct msg)); 
    ... 
} 

成功。

我不明白的是,如果我複製char [20]到char [20],並使用strcpy,應該不是很好嗎?爲什麼扔堆棧粉碎錯誤?

爲什麼,在工作的答案,是其複製struct msg類型的內存char[20]場的struct pkt內存,以及爲什麼要第三個參數是sizeof(struct msg),不是strlen的(message.data)+ 1?

+5

'strcpy'需要空終止字符串也許你沒有傳遞什麼,它預計 – juanchopanza 2014-10-17 10:22:20

+0

它是由一個模擬器運行和字符串傳遞。從功能n的長度爲20(+1表示空值)。我不知道爲什麼他們將字符串定義爲大小爲20的char數組(我不允許更改),如果他們要傳遞大小爲21的char數組。 – user2418202 2014-10-17 10:25:36

+4

是的......你不能在20個數組中保存21個元素。 – juanchopanza 2014-10-17 10:26:21

回答

4

我不明白的是,如果我複製的char [20]到char [20],並 使用的strcpy,它不應該被罰款?

如果結構信息的數據成員數據是零終止的,即它包含一個字符串,那將會很好。這似乎是錯誤的原因是它不包含字符串。 作爲該語句

memcpy(&snd_pkt.payload, &message, sizeof(struct msg)); 

然後在一般情況下,它有未定義的行爲,因爲由於結構對準的sizeof的結構可以是例如大於20個字節時的sizeof(int是等於8

4
strcpy(snd_pkt.payload, message.data); 

只有當您的char數組數據爲空時,shoud纔會合格。 或者,你可以使用:

size_t ss = sizeof(snd_pkt.payload); 
strncpy(snd_pkt.payload, message.data, ss-1); 
snd_pkt.payload[ss-1] = '\0'; 
+1

+1用於在'strncpy'之後添加'\ 0'。 – user694733 2014-10-17 10:30:30

+1

確實......但不要忘記http://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/ – Roddy 2014-10-17 10:31:14

+0

'strncpy'在這裏似乎很合適(雖然我仍然更喜歡' snprintf') – 2014-10-17 10:31:59

0
使用簡單的for循環

也不會工作得很好:

void A_output(struct msg message) { 
... 
struct pkt snd_pkt; 
int i=0, 
for(i=0;i<20;i++){ 
    snd_pkt.payload[i] = msg.data[i]; 
} 
...