我有此代码:
static void foo(char *string1, char *string2)
{
char *string1_copy= malloc(strlen(string1));
strcpy(string1_copy, haystack);
char *string2_copy = malloc(strlen(string2));
strcpy(string2_copy, needle);
}
我必须复制string1
和string2
才能修改其副本并保留原件。这会执行应做的工作,并且编译时不会出错,但是在我运行时:
valgrind --leak-check=full -v ./myProgram
我明白了:
==20595== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
==20595==
==20595== 1 errors in context 1 of 3:
==20595== Invalid read of size 1
==20595== at 0x4C376F4: strstr (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20595== by 0x108CED: grep (myProgram.c:87)
==20595== by 0x109023: main (myProgram.c:214)
==20595== Address 0x522e3b3 is 0 bytes after a block of size 3 alloc'd
==20595== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20595== by 0x108CA5: grep (myProgram.c:77)
==20595== by 0x109023: main (myProgram.c:214)
==20595==
==20595==
==20595== 1 errors in context 2 of 3:
==20595== Invalid write of size 1
==20595== at 0x4C32E0D: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20595== by 0x108CBC: grep (myProgram.c:78)
==20595== by 0x109023: main (myProgram.c:214)
==20595== Address 0x522e3b3 is 0 bytes after a block of size 3 alloc'd
==20595== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20595== by 0x108CA5: grep (myProgram.c:77)
==20595== by 0x109023: main (myProgram.c:214)
==20595==
==20595==
==20595== 1 errors in context 3 of 3:
==20595== Invalid write of size 1
==20595== at 0x4C32E0D: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20595== by 0x108C91: grep (myProgram.c:75)
==20595== by 0x109023: main (myProgram.c:214)
==20595== Address 0x522e362 is 0 bytes after a block of size 18 alloc'd
==20595== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20595== by 0x108C7A: grep (myProgram.c:74)
==20595== by 0x109023: main (myProgram.c:214)
==20595==
==20595== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
这正是我使用strcpy()
创建这2个副本以及使用strstr()
读取它们的地方。有什么办法可以避免这种情况,还是我不应该在这里使用strcpy()
?我传递的字符串的strlen(string)
大小不正确吗?
malloc
调用应为空终止符字节分配足够的空间。
坏:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *foo = "hello world";
char *bar = malloc(strlen(foo)); // <-- no
strcpy(bar, foo);
puts(bar);
free(bar);
return 0;
}
好:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *foo = "hello world";
char *bar = malloc(strlen(foo) + 1); // <-- yes
strcpy(bar, foo);
puts(bar);
free(bar);
return 0;
}