[英]Valgrind errors. Use of malloc and realloc in functions
我正在尝试使mystrcat函数正常工作。 它似乎返回正确的字符串,但是valgrind给出了我似乎无法修复的代码错误。
char *mystrcat(char *dest, const char *src) {
int len = strlen(dest) * 2;
char *origdest = realloc(dest, len);
while(*dest) {
dest++;
}
while (*src) {
*dest++ = *src++;
}
return origdest;
}
int main(void) {
char *str = malloc(7);
strcpy(str, "First");
str = mystrcat(str, "Second");
printf("%s\n", str);
free(str);
}
我不明白的Valgrind错误:
==10== Invalid read of size 1
==10== at 0x40068B: mystrcat (mystrcat.c:9)
==10== by 0x40070F: main (mystrcat.c:25)
==10== Address 0x5203040 is 0 bytes inside a block of size 7 free'd
==10== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10== by 0x40067B: mystrcat (mystrcat.c:8)
==10== by 0x40070F: main (mystrcat.c:25)
==10== Block was alloc'd at
==10== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10== by 0x4006E6: main (mystrcat.c:22)
==10==
==10== Invalid write of size 1
==10== at 0x4006AF: mystrcat (mystrcat.c:14)
==10== by 0x40070F: main (mystrcat.c:25)
==10== Address 0x5203046 is 6 bytes inside a block of size 7 free'd
==10== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10== by 0x40067B: mystrcat (mystrcat.c:8)
==10== by 0x40070F: main (mystrcat.c:25)
==10== Block was alloc'd at
==10== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10== by 0x4006E6: main (mystrcat.c:22)
您需要这个(请参阅注释以获取解释):
char *mystrcat(char *dest, const char *src) {
int len = strlen(dest) * 2;
char *newdest = realloc(dest, len);
// newdest contains the pointer to the newly allocated memory
// and dest is now no longer valid
dest = newdest;
while(*dest) {
dest++;
}
// now dest points to the end of the string in the newly
// allocated memory
while (*src) {
*dest++ = *src++;
}
// add NUL terminator
*dest = 0;
// we return the newly allocated memory
return newdest;
}
但是此功能仍不完全正确。
这是错误的:
int len = strlen(dest) * 2;
将大小加倍是错误的,因为如果src
大于dest
字符串的长度,则将没有足够的内存,并且您将获得缓冲区溢出。
串联字符串所需的内存大小为:
size of the original string + size of the string to be concatenated + 1
由于NUL
字符串终止符,因此需要+1
。
因此,您需要:
int len = strlen(dest) + strlen(src) + 1;
还有一件事:
char *mystrcat(char *dest, const char *src)
可以替换为
char *mystrcat(const char *dest, const char *src)
因为我们实际上不修改dest
指向的内存。
请注意,只有在已使用类似malloc
的函数分配了destinatino指针的情况下,您的mystrcat
才有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.