我有一个简单的程序来根据delim分割输入字符串。 算法如下:
计算我要将原始输入分成的批次大小。
根据计数大小+ 1(最后一个使其为NULL)对2D指针结果进行Malloc
调用strsep来逐个切割源(令牌)
我无法弄清楚为什么这两个free()语句会导致我 错误。在第51行:
免费(*(代币+ i));
这一行给了我以下错误:
free():指针无效
如果我在第54行注释掉这一行:
自由(令牌);
给我以下错误:
free():下一个尺寸无效(快)
我经历了关于这两个错误的讨论,但是我 仍然无法弄清楚为什么这些会导致问题 我的计划。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
char** str_split(char *str, const char *delim)
{
char *token;
char **results;
int count = 0;
int i;
for( i = 0; i < strlen(str); i++ )
//TODO: check delim format
// assume to be one char string for now
if( str[i] == *delim )
count++;
count++;
results = (char**) malloc(sizeof(char*) * count); /* line 21 */
int index = 0;
while( (token = strsep(&str, delim)) != NULL )
{
int size = strlen(token);
results[index] = (char*) malloc(sizeof(char*) * size); /* line 27 */
strcpy( results[index], token );
index++;
}
results[index] = NULL; /* line 31 */
return results;
}
int main()
{
char source[] = "name id ip";
char **tokens;
printf("source=[%s]\n\n", source);
tokens = str_split(source, " ");
if (tokens)
{
int i;
for (i = 0; *(tokens + i); i++)
{
printf("batch=[%s]\n", *(tokens + i));
free(*(tokens + i)); /* line 51*/
}
printf("\n");
free(tokens); /* line 54 */
}
return 0;
}
我还尝试了gdb来查看正在发生的事情的更多细节。我能够检查第51行的指针:
gdb> x /s *(tokens+i) 0x602030: "name"
同样在第54行:
gdb> x /s *tokens 0x602010: "0 `"
我也尝试过Valgrid来检查我的编译文件,但我不知道如何 解释这个分析:
==26070== Command: ./str_parse
==26070==
==26070== Invalid write of size 8
==26070== at 0x40086D: str_split (str_parse.c:31)
==26070== by 0x4008D4: main (str_parse.c:43)
==26070== Address 0x51fc058 is 0 bytes after a block of size 24 alloc'd
==26070== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26070== by 0x4007CB: str_split (str_parse.c:21)
==26070== by 0x4008D4: main (str_parse.c:43)
==26070==
==26070== Invalid read of size 8
==26070== at 0x40094D: main (str_parse.c:48)
==26070== Address 0x51fc058 is 0 bytes after a block of size 24 alloc'd
==26070== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26070== by 0x4007CB: str_split (str_parse.c:21)
==26070== by 0x4008D4: main (str_parse.c:43)
==26070==
==26070==
==26070== HEAP SUMMARY:
==26070== in use at exit: 0 bytes in 0 blocks
==26070== total heap usage: 4 allocs, 4 frees, 88 bytes allocated
==26070==
==26070== All heap blocks were freed -- no leaks are possible
==26070==
==26070== For counts of detected and suppressed errors, rerun with: -v
==26070== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
答案 0 :(得分:1)
我认为罪魁祸首是:
results[index] = NULL;
我怀疑此时index
的值为count
,它使用越界索引修改results
。这导致了不确定的行为。如果要使用此方法,则需要使用:
results = malloc(sizeof(char*) * (count+1));
请参阅Do I cast the result of malloc?。
此外,您使用的是错误的大小来为字符串本身分配内存。
您正在使用:
results[index] = (char*) malloc(sizeof(char*) * size)
strcpy( results[index], token );
应该是:
results[index] = malloc(size+1)
strcpy( results[index], token );
答案 1 :(得分:0)
感谢Sahu先生的投入。我仔细阅读了您提供的链接。我将从现在开始纠正我对malloc的使用。我想我早就从某个地方学到了它。直到今天,它还没有意识到这是一个糟糕的编码。
另外,我意识到我没有将malloc区域增加一个以留出空间来进行操作。\ 0&#39;我修改了我的原始代码,它工作了!!!
results = malloc(sizeof(char*) * (count+1));
results[index] = malloc(sizeof(char*) * (size+1) );
results[count] = NULL;