简体   繁体   English

使用strcpy引发“检测到堆栈粉碎”错误

[英]Using strcpy throws “stack smashing detected” error

I have two types of struct s, struct msg and struct pkt . 我有两种类型的structstruct msgstruct pkt My job is to construct a struct pkt using struct msg passed as an argument. 我的工作是使用作为参数传递的struct msg构造一个struct pkt

struct msg {
  char data[20];
  };

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

While

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

fails, 失败,

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

succeeds. 成功。

What I do not understand is, if I am copying char[20] to char[20], and used strcpy , shouldn't it be fine? 我不明白的是,如果我将char [20]复制到char [20]并使用strcpy ,那还好吗? Why is it throwing stack smashing error? 为什么会抛出堆栈粉碎错误?

Why, in the working answer, is it copying memory of type struct msg to the memory of char[20] field in struct pkt , and why should the third argument be sizeof(struct msg) , not strlen(message.data) + 1? 在工作答案中,为什么将struct msg类型的内存复制到struct pktchar[20]字段的内存中,为什么第三个参数应该是sizeof(struct msg)而不是strlen(message.data)+ 1 ?

strcpy(snd_pkt.payload, message.data);

shoud be fine only if your char array data is null terminated. 仅当您的char数组数据以null终止时,才应该没问题。 Alternately, you may use: 或者,您可以使用:

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

What I do not understand is, if I am copying char[20] to char[20], and used strcpy, shouldn't it be fine? 我不明白的是,如果我将char [20]复制到char [20],并使用strcpy,那还好吗?

It will be fine if data member data of structure msg is zero terminated that is if it contains a string. 如果结构msg的数据成员数据以零结尾(即它包含字符串)会很好。 It seems that ther reason of the error is that it does not contain a string. 似乎错误的另一个原因是它不包含字符串。 As for this statement 至于这个说法

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

then in general case it has undefined behaviour because due to the structure alignment the sizeof the structure can be greater than 20 bytes for example when sizeof( int is equal to 8. 那么通常情况下它具有不确定的行为,因为由于结构对齐,例如sizeof(int等于8时,结构的大小可以大于20个字节。

Using a simple for loop also does the job pretty well: 使用简单的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];
}
...

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

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