1. ホーム
  2. c

[解決済み】Valgrind - strcpyのサイズ1の無効な書き込み

2022-01-18 08:34:55

質問

私の swapData 関数は基本的に char* 型の 2 つのノード間でデータを交換します。

{コード

valgrindを実行すると、いつもこのような出力が出ます。

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  }

swapDataのstrcpyに問題があるのではと思います。どなたか教えていただけませんか?

解決方法は?

mallocの長さに1を足すだけでなく、あなたがやっているようにstrcpyを使って文字列を入れ替えることはできません。 もし、最初の文字列が10バイトで、2番目の文字列が29バイトでmallocされたとしたらどうでしょう? スワップするためにコピーすると、最初の文字列のバッファをオーバーランすることになります。 ポインターをスワップするのがベストでしょう。 もし ==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== が固定長の配列として定義されている場合、あなたがやっていることは問題ありませんが、その場合 {コード {コード は、ノードの代わりに同じ大きさの配列にすることもできます。