Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 大文件的双重释放或损坏(fasttop)_C_Realloc_Strtok_Corruption - Fatal编程技术网

C 大文件的双重释放或损坏(fasttop)

C 大文件的双重释放或损坏(fasttop),c,realloc,strtok,corruption,C,Realloc,Strtok,Corruption,我正在编写一个程序,用来读取大的CSV文件。我用更小的CSV文件进行了开发和测试,并进行了调试,效果良好。但当我使用一个真正的(17k行),它开始不工作 下面是有问题的函数(包含所有文件): 我做了一个测试,临界点在1202行,如果我的CSV得到更多行,程序将返回以下错误: *** Error in `test.x': double free or corruption (fasttop): 0x00000000018adfc0 *** 我是用Valgrind做的: valgrind --le

我正在编写一个程序,用来读取大的CSV文件。我用更小的CSV文件进行了开发和测试,并进行了调试,效果良好。但当我使用一个真正的(17k行),它开始不工作

下面是有问题的函数(包含所有文件):

我做了一个测试,临界点在1202行,如果我的CSV得到更多行,程序将返回以下错误:

*** Error in `test.x': double free or corruption (fasttop): 0x00000000018adfc0 ***
我是用Valgrind做的:

valgrind --leak-check=yes test.x
它还给我这个:

==2132== Memcheck, a memory error detector
==2132== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==2132== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==2132== Command: test.x
==2132== 
0 3 -1 -1 -1 -1 -1 -1 -1 -1 -1
==2132== Invalid free() / delete / delete[] / realloc()
==2132==    at 0x4C2AF2E: realloc (vg_replace_malloc.c:692)
==2132==    by 0x4011B3: _add_to_tab (split_string.c:5)
==2132==    by 0x40124F: st_split (split_string.c:26)
==2132==    by 0x40109E: lecture_fichier (lecture_fichier.c:108)
==2132==    by 0x40134A: main (test.c:11)
==2132==  Address 0x54e12c0 is 0 bytes inside a block of size 8 free'd
==2132==    at 0x4C2AF2E: realloc (vg_replace_malloc.c:692)
==2132==    by 0x4011B3: _add_to_tab (split_string.c:5)
==2132==    by 0x40124F: st_split (split_string.c:26)
==2132==    by 0x40109E: lecture_fichier (lecture_fichier.c:108)
==2132==    by 0x40134A: main (test.c:11)
==2132== 
==2132== Invalid write of size 8
==2132==    at 0x4011CE: _add_to_tab (split_string.c:6)
==2132==    by 0x40124F: st_split (split_string.c:26)
==2132==    by 0x40109E: lecture_fichier (lecture_fichier.c:108)
==2132==    by 0x40134A: main (test.c:11)
==2132==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
==2132== 
==2132== 
==2132== Process terminating with default action of signal 11 (SIGSEGV)
==2132==  Access not within mapped region at address 0x8
==2132==    at 0x4011CE: _add_to_tab (split_string.c:6)
==2132==    by 0x40124F: st_split (split_string.c:26)
==2132==    by 0x40109E: lecture_fichier (lecture_fichier.c:108)
==2132==    by 0x40134A: main (test.c:11)
==2132==  If you believe this happened as a result of a stack
==2132==  overflow in your program's main thread (unlikely but
==2132==  possible), you can try to increase the size of the
==2132==  main thread stack using the --main-stacksize= flag.
==2132==  The main thread stack size used in this run was 8388608.
==2132== 
==2132== HEAP SUMMARY:
==2132==     in use at exit: 576 bytes in 2 blocks
==2132==   total heap usage: 4 allocs, 2 frees, 600 bytes allocated
==2132== 
==2132== 8 bytes in 1 blocks are definitely lost in loss record 1 of 2
==2132==    at 0x4C2AF2E: realloc (vg_replace_malloc.c:692)
==2132==    by 0x4011B3: _add_to_tab (split_string.c:5)
==2132==    by 0x40124F: st_split (split_string.c:26)
==2132==    by 0x40109E: lecture_fichier (lecture_fichier.c:108)
==2132==    by 0x40134A: main (test.c:11)
==2132== 
==2132== LEAK SUMMARY:
==2132==    definitely lost: 8 bytes in 1 blocks
==2132==    indirectly lost: 0 bytes in 0 blocks
==2132==      possibly lost: 0 bytes in 0 blocks
==2132==    still reachable: 568 bytes in 1 blocks
==2132==         suppressed: 0 bytes in 0 blocks
==2132== Reachable blocks (those to which a pointer was found) are not shown.
==2132== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==2132== 
==2132== For counts of detected and suppressed errors, rerun with: -v
==2132== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
问题就在这里

void _add_to_tab(char** ret, char* string, unsigned int len)
{
    ret = realloc(ret, (len + 1)*sizeof(char*));
    ret[len] = string;
}
当realloc返回一个不同的指针时,只有本地
ret
被更改,但没有传递给调用者,因此调用者仍然使用以前的、现在无效的指针

换成

char **_add_to_tab(char** ret, char* string, unsigned int len)
{
    ret = realloc(ret, (len + 1)*sizeof(char*));
    ret[len] = string;
    return ret;
}
并称之为

ret = _add_to_tab(ret, tmp, len);

不要忘记添加一些错误检查(realloc可能返回NULL)

事实上,如果
realloc
返回
NULL
,则
ret[len]=string上面的行将中断。函数应该避免这种情况,但它可以让调用方处理函数返回
NULL
的剩余后果。在这种情况下,旧指针仍然有效,因此调用方应该保留旧指针的副本以进行错误处理。
ret = _add_to_tab(ret, tmp, len);