重新分配:无效的下一个大小错误
realloc: invalid next size error
我在 realloc
中遇到了这个错误,它只发生在我学校的实验室计算机上,而不是我的。
在这个程序中,我将行号存储在 File_Node
结构中。 File_Node
是链表的一部分,每个节点包含文件路径字符串和文件中的数组行号。
在需要存储太多行号 (> 3000) 之前,该程序工作正常。
这是我的代码的相关部分:
if ((token = strtok(NULL, delim)) != NULL) {
char *endptr = NULL;
int *linenum_tmp = NULL;
long line_number;
errno = 0;
line_number = strtol(token, &endptr, 10);
if (errno == ERANGE) {
exit_program("Integer overflow.");
}
if (*endptr != '[=10=]' || endptr == token || line_number < 0) {
exit_program("Cannot parse line number input.");
}
if (tail->line_numbers == NULL) {
tail->line_numbers = malloc(num_array_sz * sizeof(int));
}
if (counter == num_array_sz) { //Area of interest
num_array_sz *= 2;
if ((linenum_tmp = realloc(tail->line_numbers, sizeof(int) * num_array_sz)) == NULL) {
exit_program("Error in realloc.");
}
}
*(tail->line_numbers + counter - 1) = line_number;
} else {
exit_program("Cannot parse line number input.");
}
counter++;
上面的代码是一个更大的 while 循环的一部分,它包含更多行,但如果需要,我会 post 它。这就是为什么底部有一个 counter++
的原因。我基本上每次 counter
表示存储的行数达到 num_array_sz
时 num_array_sz
的大小加倍,它被初始化为 256
.
在我自己的电脑上,我用比学校电脑更多的输入测试了它,它运行完美。
我想知道这是否是由于我学校计算机上的 ram 有限或可能是平台不同造成的。
这里是我运行在学校电脑上的valgrind输出:
==1579== Memcheck, a memory error detector
==1579== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==1579== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==1579== Command: ./rgpp_v2 -w the -b -n
==1579==
==1579== Invalid write of size 4
==1579== at 0x40110E: process_input (rgpp_v2.c:181)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579== Address 0x51e0b9c is 1,020 bytes inside a block of size 1,024 free'd
==1579== at 0x4C29B7E: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1579== by 0x4010DD: process_input (rgpp_v2.c:177)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579==
==1579== Invalid free() / delete / delete[] / realloc()
==1579== at 0x4C29B7E: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1579== by 0x4010DD: process_input (rgpp_v2.c:177)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579== Address 0x51e07a0 is 0 bytes inside a block of size 1,024 free'd
==1579== at 0x4C29B7E: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1579== by 0x4010DD: process_input (rgpp_v2.c:177)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579==
Error in realloc.
==1579==
==1579== HEAP SUMMARY:
==1579== in use at exit: 3,477 bytes in 9 blocks
==1579== total heap usage: 12 allocs, 3 frees, 8,717 bytes allocated
==1579==
==1579== LEAK SUMMARY:
==1579== definitely lost: 2,048 bytes in 1 blocks
==1579== indirectly lost: 0 bytes in 0 blocks
==1579== possibly lost: 0 bytes in 0 blocks
==1579== still reachable: 1,429 bytes in 8 blocks
==1579== suppressed: 0 bytes in 0 blocks
==1579== Rerun with --leak-check=full to see details of leaked memory
==1579==
==1579== For counts of detected and suppressed errors, rerun with: -v
==1579== ERROR SUMMARY: 34 errors from 2 contexts (suppressed: 2 from 2)
这些错误指向 realloc
行。
您没有正确使用 realloc
。
linenum_tmp = realloc(tail->line_numbers, ....
...
*(tail->line_numbers + counter - 1) = ...
如果realloc
需要重新分配你的内存,你传递给它的指针是freed
。然后,您继续使用 tail->line_numbers
的 旧的、释放的 值。
您必须始终使用 realloc
的 return 值 。
我想你想要的是:
tail->line_numbers = realloc(tail->line_numbers, ...
其次,您误解了 valgrind
告诉您的内容。
==1579== Invalid write of size 4
==1579== at 0x40110E: process_input (rgpp_v2.c:181)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579== Address 0x51e0b9c is 1,020 bytes inside a block of size 1,024 free'd
==1579== at 0x4C29B7E: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1579== by 0x4010DD: process_input (rgpp_v2.c:177)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
它的意思是:在函数 process_input
中(在 rgpp_v2.c
的第 181 行),您正在访问以前 free
d 的内存。供您参考,它之前由 realloc
释放,由 process_input
在 rgpp_v2.c
.
的第 177 行调用
if (counter == num_array_sz) { //Area of interest
num_array_sz *= 2;
if ((linenum_tmp = realloc(tail->line_numbers, sizeof(int) * num_array_sz)) == NULL) {
exit_program("Error in realloc.");
}
}
*(tail->line_numbers + counter - 1) = line_number;
您需要使用 realloc
的结果更新您的工作变量,如下所示:
if (counter == num_array_sz) { //Area of interest
num_array_sz *= 2;
if ((linenum_tmp = realloc(tail->line_numbers, sizeof(int) * num_array_sz)) == NULL) {
exit_program("Error in realloc.");
}
}
tail->line_numbers = linenum_tmp; // <---!
*(tail->line_numbers + counter - 1) = line_number;
我在 realloc
中遇到了这个错误,它只发生在我学校的实验室计算机上,而不是我的。
在这个程序中,我将行号存储在 File_Node
结构中。 File_Node
是链表的一部分,每个节点包含文件路径字符串和文件中的数组行号。
在需要存储太多行号 (> 3000) 之前,该程序工作正常。
这是我的代码的相关部分:
if ((token = strtok(NULL, delim)) != NULL) {
char *endptr = NULL;
int *linenum_tmp = NULL;
long line_number;
errno = 0;
line_number = strtol(token, &endptr, 10);
if (errno == ERANGE) {
exit_program("Integer overflow.");
}
if (*endptr != '[=10=]' || endptr == token || line_number < 0) {
exit_program("Cannot parse line number input.");
}
if (tail->line_numbers == NULL) {
tail->line_numbers = malloc(num_array_sz * sizeof(int));
}
if (counter == num_array_sz) { //Area of interest
num_array_sz *= 2;
if ((linenum_tmp = realloc(tail->line_numbers, sizeof(int) * num_array_sz)) == NULL) {
exit_program("Error in realloc.");
}
}
*(tail->line_numbers + counter - 1) = line_number;
} else {
exit_program("Cannot parse line number input.");
}
counter++;
上面的代码是一个更大的 while 循环的一部分,它包含更多行,但如果需要,我会 post 它。这就是为什么底部有一个 counter++
的原因。我基本上每次 counter
表示存储的行数达到 num_array_sz
时 num_array_sz
的大小加倍,它被初始化为 256
.
在我自己的电脑上,我用比学校电脑更多的输入测试了它,它运行完美。
我想知道这是否是由于我学校计算机上的 ram 有限或可能是平台不同造成的。
这里是我运行在学校电脑上的valgrind输出:
==1579== Memcheck, a memory error detector
==1579== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==1579== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==1579== Command: ./rgpp_v2 -w the -b -n
==1579==
==1579== Invalid write of size 4
==1579== at 0x40110E: process_input (rgpp_v2.c:181)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579== Address 0x51e0b9c is 1,020 bytes inside a block of size 1,024 free'd
==1579== at 0x4C29B7E: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1579== by 0x4010DD: process_input (rgpp_v2.c:177)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579==
==1579== Invalid free() / delete / delete[] / realloc()
==1579== at 0x4C29B7E: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1579== by 0x4010DD: process_input (rgpp_v2.c:177)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579== Address 0x51e07a0 is 0 bytes inside a block of size 1,024 free'd
==1579== at 0x4C29B7E: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1579== by 0x4010DD: process_input (rgpp_v2.c:177)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579==
Error in realloc.
==1579==
==1579== HEAP SUMMARY:
==1579== in use at exit: 3,477 bytes in 9 blocks
==1579== total heap usage: 12 allocs, 3 frees, 8,717 bytes allocated
==1579==
==1579== LEAK SUMMARY:
==1579== definitely lost: 2,048 bytes in 1 blocks
==1579== indirectly lost: 0 bytes in 0 blocks
==1579== possibly lost: 0 bytes in 0 blocks
==1579== still reachable: 1,429 bytes in 8 blocks
==1579== suppressed: 0 bytes in 0 blocks
==1579== Rerun with --leak-check=full to see details of leaked memory
==1579==
==1579== For counts of detected and suppressed errors, rerun with: -v
==1579== ERROR SUMMARY: 34 errors from 2 contexts (suppressed: 2 from 2)
这些错误指向 realloc
行。
您没有正确使用 realloc
。
linenum_tmp = realloc(tail->line_numbers, ....
...
*(tail->line_numbers + counter - 1) = ...
如果realloc
需要重新分配你的内存,你传递给它的指针是freed
。然后,您继续使用 tail->line_numbers
的 旧的、释放的 值。
您必须始终使用 realloc
的 return 值 。
我想你想要的是:
tail->line_numbers = realloc(tail->line_numbers, ...
其次,您误解了 valgrind
告诉您的内容。
==1579== Invalid write of size 4
==1579== at 0x40110E: process_input (rgpp_v2.c:181)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
==1579== Address 0x51e0b9c is 1,020 bytes inside a block of size 1,024 free'd
==1579== at 0x4C29B7E: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1579== by 0x4010DD: process_input (rgpp_v2.c:177)
==1579== by 0x400DCC: main (rgpp_v2.c:103)
它的意思是:在函数 process_input
中(在 rgpp_v2.c
的第 181 行),您正在访问以前 free
d 的内存。供您参考,它之前由 realloc
释放,由 process_input
在 rgpp_v2.c
.
if (counter == num_array_sz) { //Area of interest
num_array_sz *= 2;
if ((linenum_tmp = realloc(tail->line_numbers, sizeof(int) * num_array_sz)) == NULL) {
exit_program("Error in realloc.");
}
}
*(tail->line_numbers + counter - 1) = line_number;
您需要使用 realloc
的结果更新您的工作变量,如下所示:
if (counter == num_array_sz) { //Area of interest
num_array_sz *= 2;
if ((linenum_tmp = realloc(tail->line_numbers, sizeof(int) * num_array_sz)) == NULL) {
exit_program("Error in realloc.");
}
}
tail->line_numbers = linenum_tmp; // <---!
*(tail->line_numbers + counter - 1) = line_number;