在循环中使用一个 malloc() 和一个 free() 双重释放或损坏 (!prev)
Double free or corruption (!prev) with one malloc() and one free() in a loop
我正在通过编写 string.h 库的函数来练习 C。但我目前遇到了一个我不明白的问题。当我执行我的程序时,它崩溃并显示以下消息:
double free or corruption (!prev)
我尝试使用 Valgrind,但似乎没有出现错误。
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
char * duplicateString(const char * str) {
size_t strLength = strlen(str);
char * duplicatedString = malloc(strLength);
if(duplicatedString == NULL)
exit(EXIT_FAILURE);
// +1 to copy '[=10=]'
strncpy(duplicatedString, str, strLength + 1);
return duplicatedString;
}
void test_duplicateString()
{
const char * src = "abc";
char buf[1024];
int i, j;
char * temp = duplicateString(src);
assert((strcmp((src),(temp)) == 0));
assert(src != temp);
free(temp);
for(i = 0; i < 1024; ++i)
{
for(j = 0; j < i; ++j)
buf[j] = (char) ('a' + (j % 26));
buf[i] = '[=10=]';
temp = duplicateString(buf);
assert((strcmp((buf),(temp)) == 0));
free(temp);
}
}
int main()
{
test_duplicateString();
return 0;
}
根据GDB,当i=136时,这个错误总是发生在第38行。
例如,为什么在 i=136,而不是之前?
#0 0x00007ffff7a6a5f8 in raise () from /usr/lib/libc.so.6
No symbol table info available.
#1 0x00007ffff7a6ba7a in abort () from /usr/lib/libc.so.6
No symbol table info available.
#2 0x00007ffff7aa905a in __libc_message () from /usr/lib/libc.so.6
No symbol table info available.
#3 0x00007ffff7aae9a6 in malloc_printerr () from /usr/lib/libc.so.6
No symbol table info available.
#4 0x00007ffff7aaf18e in _int_free () from /usr/lib/libc.so.6
No symbol table info available.
#5 0x000000000040093e in test_duplicateString () at /media/sf_data/Cours/Polytech/DI3/Langage_C/DoubleFreeTest/main.c:38
src = 0x400a10 "abc"
buf = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef[=11=]047777[=11=]0[=11=]0057777[=11=]0[=11=]0x05777[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0017777[=11=]0[=11=]0`67777[=11=]0[=11=]0?M6777[=11=]0[=11=]0[=11=]1[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0"...
i = 136
j = 136
temp = 0x602010 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef"
__PRETTY_FUNCTION__ = "test_duplicateString"
#6 0x0000000000400979 in main () at /media/sf_data/Cours/Polytech/DI3/Langage_C/DoubleFreeTest/main.c:44
No locals.
要将所有评论所说的内容放入答案中,在您的函数 duplicateString()
中,您没有分配足够的内存来容纳字符串 和 null字符.
所以当你这样做的时候
strncpy(duplicatedString, str, strLength + 1);
您复制的内容超出了缓冲区的容量。解决方案显然是将缓冲区大小增加 1.
char * duplicatedString = malloc(strLength + 1);
我正在通过编写 string.h 库的函数来练习 C。但我目前遇到了一个我不明白的问题。当我执行我的程序时,它崩溃并显示以下消息:
double free or corruption (!prev)
我尝试使用 Valgrind,但似乎没有出现错误。
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
char * duplicateString(const char * str) {
size_t strLength = strlen(str);
char * duplicatedString = malloc(strLength);
if(duplicatedString == NULL)
exit(EXIT_FAILURE);
// +1 to copy '[=10=]'
strncpy(duplicatedString, str, strLength + 1);
return duplicatedString;
}
void test_duplicateString()
{
const char * src = "abc";
char buf[1024];
int i, j;
char * temp = duplicateString(src);
assert((strcmp((src),(temp)) == 0));
assert(src != temp);
free(temp);
for(i = 0; i < 1024; ++i)
{
for(j = 0; j < i; ++j)
buf[j] = (char) ('a' + (j % 26));
buf[i] = '[=10=]';
temp = duplicateString(buf);
assert((strcmp((buf),(temp)) == 0));
free(temp);
}
}
int main()
{
test_duplicateString();
return 0;
}
根据GDB,当i=136时,这个错误总是发生在第38行。 例如,为什么在 i=136,而不是之前?
#0 0x00007ffff7a6a5f8 in raise () from /usr/lib/libc.so.6
No symbol table info available.
#1 0x00007ffff7a6ba7a in abort () from /usr/lib/libc.so.6
No symbol table info available.
#2 0x00007ffff7aa905a in __libc_message () from /usr/lib/libc.so.6
No symbol table info available.
#3 0x00007ffff7aae9a6 in malloc_printerr () from /usr/lib/libc.so.6
No symbol table info available.
#4 0x00007ffff7aaf18e in _int_free () from /usr/lib/libc.so.6
No symbol table info available.
#5 0x000000000040093e in test_duplicateString () at /media/sf_data/Cours/Polytech/DI3/Langage_C/DoubleFreeTest/main.c:38
src = 0x400a10 "abc"
buf = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef[=11=]047777[=11=]0[=11=]0057777[=11=]0[=11=]0x05777[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0017777[=11=]0[=11=]0`67777[=11=]0[=11=]0?M6777[=11=]0[=11=]0[=11=]1[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0"...
i = 136
j = 136
temp = 0x602010 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef"
__PRETTY_FUNCTION__ = "test_duplicateString"
#6 0x0000000000400979 in main () at /media/sf_data/Cours/Polytech/DI3/Langage_C/DoubleFreeTest/main.c:44
No locals.
要将所有评论所说的内容放入答案中,在您的函数 duplicateString()
中,您没有分配足够的内存来容纳字符串 和 null字符.
所以当你这样做的时候
strncpy(duplicatedString, str, strLength + 1);
您复制的内容超出了缓冲区的容量。解决方案显然是将缓冲区大小增加 1.
char * duplicatedString = malloc(strLength + 1);