C语言 Valgrind - strcpy 的大小 1 写入无效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26685936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Valgrind - Invalid write of size 1 for strcpy
提问by viethaihp291
My swapData function basically swaps data between two node of type char*
我的 swapData 函数基本上在两个 char* 类型的节点之间交换数据
17 void swapData(struct Node *node1, struct Node *node2)
18 {
19 // Create a new node "temp" that stores the data of node2
20 struct Node *temp = (struct Node *)malloc(sizeof(struct Node));
21 temp->data = malloc(strlen(node2->data));
22
23 strcpy(temp->data,node2->data);
24
25 // Copy data from node1 to node2
26 strcpy(node2->data,node1->data);
27
28 // Copy data from temp to node1
29 strcpy(node1->data,temp->data);
30
31 free(temp->data);
32 free(temp);
33 }
Whenever I run valgrind, it keeps giving me this output:
每当我运行 valgrind 时,它都会不断给我这个输出:
==27570== Invalid write of size 1
==27570== at 0x4C2C00F: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27570== by 0x400794: swapData (test4.c:23)
==27570== by 0x400A9C: sort (list2.c:20)
==27570== by 0x40086B: main (test4.c:49)
==27570== Address 0x51f11dd is 0 bytes after a block of size 13 alloc'd
==27570== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27570== by 0x40076B: swapData (test4.c:21)
==27570== by 0x400A9C: sort (list2.c:20)
==27570== by 0x40086B: main (test4.c:49)
==27570==
==27570== Source and destination overlap in strcpy(0x51f1130, 0x51f1130)
==27570== at 0x4C2C085: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27570== by 0x4007B2: swapData (test4.c:26)
==27570== by 0x400A9C: sort (list2.c:20)
==27570== by 0x40086B: main (test4.c:49)
==27570==
==27570== Invalid read of size 1
==27570== at 0x4C2C002: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27570== by 0x4007D0: swapData (test4.c:29)
==27570== by 0x400A9C: sort (list2.c:20)
==27570== by 0x40086B: main (test4.c:49)
==27570== Address 0x51f11dd is 0 bytes after a block of size 13 alloc'd
==27570== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27570== by 0x40076B: swapData (test4.c:21)
==27570== by 0x400A9C: sort (list2.c:20)
==27570== by 0x40086B: main (test4.c:49)
==27570==
I believe the problem is in strcpy in swapData. Can someone tell me what's going on?
我相信问题出在 swapData 中的 strcpy 中。有人可以告诉我这是怎么回事吗?
回答by Kaizhe Huang
You need to malloc one more byte for temp->data
您需要为 temp->data 再分配一个字节
temp->data = malloc(strlen(node2->data)+1);
This is because you need the final byte to store then '\0' indicating the end of the string.
这是因为您需要存储最后一个字节,然后 '\0' 表示字符串的结尾。
回答by JS1
Not only do you need to add one to your malloc length, but also you can't swap strings using strcpy like you are doing. What if the first string was malloced with 10 bytes and the second with 29 bytes? When you copy to swap, you will overrun the first string's buffer. It would be best to swap the pointers. If datais defined as a fixed length array, then what you are doing is ok, but then tempcould also be the same sized array instead of a node.
您不仅需要在 malloc 长度上加一个,而且还不能像现在一样使用 strcpy 交换字符串。如果第一个字符串被分配了 10 个字节,第二个被分配了 29 个字节会怎样?当您复制到交换时,您将溢出第一个字符串的缓冲区。最好是交换指针。如果data被定义为固定长度的数组,那么您所做的就temp可以了,但也可以是相同大小的数组而不是节点。

