C - String数组realloc()内存错误

时间:2014-05-15 21:42:06

标签: c arrays realloc

我正在尝试将长字符串拆分为标记,存储到以NULL结尾的字符串数组中。为此,我每次使用realloc将数组大小加倍。但是valgrind告诉我,有一些重要的问题。这是代码:

char** split_token(char* str,char* delimiter)
{
int token_buffer_size=256;
int nb_token=0;
char* token;
char** tab_token=calloc(token_buffer_size,sizeof(char*));
test_ptr(tab_token,PARAM_MACRO_TEST);
token=strtok(str,delimiter);
while(token!=NULL) 
{
    if(nb_token>=token_buffer_size)
    {
        token_buffer_size=token_buffer_size*2;
        tab_token=realloc(tab_token,token_buffer_size);
        test_ptr(tab_token,PARAM_MACRO_TEST);
    }
    printf("nb_token : %d\n",nb_token);
    tab_token[nb_token]=calloc(strlen(token)+1,sizeof(char));
    test_ptr(tab_token[nb_token],PARAM_MACRO_TEST);
    strncpy(tab_token[nb_token],token,sizeof(char)*strlen(token));
    nb_token++;
    token=strtok(NULL,delimiter);
}
tab_token[nb_token+1]=NULL;
return tab_token;
}

test_ptr()是一个基本函数,测试ptr是否为NULL。调用该函数时使用长字符串进行拆分(str),并使用strtok的分隔符(此处为“\ n”)。当解雇valgrind时,这就是我得到的:

nb_token : 256
==8737== Invalid write of size 8
==8737==    at 0x59E8E98: split_token (parse.c:27)
==8737==    by 0x59EAA13: recdir (libplugin.c:439)
==8737==    by 0x401C09: execute_plugin (loadlib.c:53)
==8737==    by 0x400EF9: main (main.c:23)
==8737==  Address 0x5470ce0 is not stack'd, malloc'd or (recently) free'd
==8737== 
==8737== Invalid read of size 8
==8737==    at 0x59E8EB9: split_token (parse.c:28)
==8737==    by 0x59EAA13: recdir (libplugin.c:439)
==8737==    by 0x401C09: execute_plugin (loadlib.c:53)
==8737==    by 0x400EF9: main (main.c:23)
==8737==  Address 0x5470ce0 is not stack'd, malloc'd or (recently) free'd
==8737== 
==8737== Invalid read of size 8
==8737==    at 0x59E8EFA: split_token (parse.c:29)
==8737==    by 0x59EAA13: recdir (libplugin.c:439)
==8737==    by 0x401C09: execute_plugin (loadlib.c:53)
==8737==    by 0x400EF9: main (main.c:23)
==8737==  Address 0x5470ce0 is not stack'd, malloc'd or (recently) free'd
==8737== 
nb_token : 257

因此,在重新分配选项卡(因此大小为512 tab_token)之后,似乎将字符串存储到tab_token [256]失败。我完全不知道为什么。谢谢你的关注。

1 个答案:

答案 0 :(得分:3)

此:

tab_token=realloc(tab_token,token_buffer_size);

应该是:

tab_token=realloc(tab_token, token_buffer_size*sizeof(*tab_token));

calloc()使用item-count和item-size,但realloc()使用 bytes 。在调整大小时考虑到这一点。