[英]Valgrind errors. Use of malloc and realloc in functions
I am trying to make mystrcat function to work. 我正在尝试使mystrcat函数正常工作。 It seems to return right string but valgrind gives errors on my code which I cant seem to fix.
它似乎返回正确的字符串,但是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 errors which I don't understand: 我不明白的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)
You need this (see comments for explanations): 您需要这个(请参阅注释以获取解释):
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;
}
But this function is still not entirely correct. 但是此功能仍不完全正确。
This is wrong: 这是错误的:
int len = strlen(dest) * 2;
Doubling the size is wrong, because if src
is longer than the length of the dest
string, there won't be enough memory and you'll get a buffer overflow. 将大小加倍是错误的,因为如果
src
大于dest
字符串的长度,则将没有足够的内存,并且您将获得缓冲区溢出。
The memory size needed for the concatenated string is: 串联字符串所需的内存大小为:
size of the original string + size of the string to be concatenated + 1
The +1
is needed because of the NUL
string terminator. 由于
NUL
字符串终止符,因此需要+1
。
You therefore need this: 因此,您需要:
int len = strlen(dest) + strlen(src) + 1;
And another thing: 还有一件事:
char *mystrcat(char *dest, const char *src)
can be replaced by 可以替换为
char *mystrcat(const char *dest, const char *src)
because we actually don't modify the memory pointed by dest
. 因为我们实际上不修改
dest
指向的内存。
Be aware that your mystrcat
only works if the destinatino pointer has been allocated with a malloc
-like function. 请注意,只有在已使用类似
malloc
的函数分配了destinatino指针的情况下,您的mystrcat
才有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.