我无法弄清楚我在这里做错了什么。一般是valgrind和C的新手,但已经设法清理了我所有的mem泄漏,除了这个
==8749== HEAP SUMMARY:
==8749== in use at exit: 880 bytes in 11 blocks
==8749== total heap usage: 80 allocs, 69 frees, 5,620 bytes allocated
==8749==
==8749== 400 bytes in 5 blocks are definitely lost in loss record 1 of 2
==8749== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8749== by 0x402B1C: tokenize (tm_utility.c:78)
==8749== by 0x402E57: load_data (tm_utility.c:188)
==8749== by 0x400D0A: main (tm.c:57)
==8749==
==8749== 480 bytes in 6 blocks are definitely lost in loss record 2 of 2
==8749== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8749== by 0x402B1C: tokenize (tm_utility.c:78)
==8749== by 0x402C97: load_data (tm_utility.c:147)
==8749== by 0x400D0A: main (tm.c:57)
==8749==
它与此功能有关:
char** tokenize(const char* input)
{
char* str = (char*)strdup(input);
int count = 0;
int capacity = 10;
char** result = malloc(capacity*sizeof(*result)); /*LINE 78*/
char* tok=strtok(str,",");
while(1)
{
if (count >= capacity)
result = realloc(result, (capacity*=2)*sizeof(*result));
result[count++] = tok? strdup(tok) : tok;
if (!tok) break;
tok=strtok(NULL,",");
}
free(str);
return result;
}
我可以看到我没有在那里释放一些东西,但我无法弄清楚在哪里释放它(调用函数或本地??)以及我应该释放的确切内容?
帮助?
谢谢
编辑:
下面是来自调用函数的代码。我不知道我还需要释放什么,尝试了一些不同的东西,但只是让它变得更糟,最终在这里发布。
while (fgets(line, sizeof(line), coinsfile_stream) != NULL)
{
tokens = tokenize(line);
for(i=tokens; i && *i; ++i)
{
if(y==0)
{
tm->coins[x].denomination = atoi(*i);
y=1;
x++;
}
else
{
tm->coins[z].count = atoi(*i);
y=0;
z++;
}
free(*i);
}
}
在load_data()
中调用tokenize()
的代码似乎负责执行释放。 将分配的空间返回到调用函数。
现在,问题中显示了额外的代码,您需要在处理令牌的for
循环之后添加一个free(tokens);
。 下面的代码以 valgrind
的干净健康账单运行:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **tokenize(const char *input);
char **tokenize(const char *input)
{
char *str = (char *)strdup(input);
int count = 0;
int capacity = 10;
char **result = malloc(capacity*sizeof(*result)); /*LINE 78*/
char *tok = strtok(str, ",n");
while (1)
{
printf("Found: <<%s>>n", tok);
if (count >= capacity)
result = realloc(result, (capacity *= 2)*sizeof(*result));
result[count++] = tok ? strdup(tok) : tok;
if (!tok)
break;
tok = strtok(NULL, ",n");
}
free(str);
return result;
}
int main(void)
{
char line[1024];
int x = 0;
int y = 0;
int z = 0;
struct Coin {
int denomination;
int count;
};
struct Trade {
struct Coin coins[10];
};
struct Trade tm1;
struct Trade *tm = &tm1;
while (fgets(line, sizeof(line), stdin) != NULL)
{
char **tokens = tokenize(line);
for (char **i = tokens; i && *i; ++i)
{
printf("Token: <<%s>>n", *i);
if (y == 0)
{
tm->coins[x].denomination = atoi(*i);
y = 1;
x++;
}
else
{
tm->coins[z].count = atoi(*i);
y = 0;
z++;
}
free(*i);
}
free(tokens);
}
}
数据文件:
12,23
34,45
56,67
示例输出:
Found: <<12>>
Found: <<23>>
Found: <<(null)>>
Token: <<12>>
Token: <<23>>
Found: <<34>>
Found: <<45>>
Found: <<(null)>>
Token: <<34>>
Token: <<45>>
Found: <<56>>
Found: <<67>>
Found: <<(null)>>
Token: <<56>>
Token: <<67>>
当心:我的代码依赖于我正在使用的系统(Mac OS X 10.9 Mavericks;GCC 4.8.2 — 但valgrind
在同一平台上托管的古老 Linux VM 中运行)当要求打印空指针指向的字符串时不会崩溃。 您需要查看while (1)
循环;您可能应该将其更改为 while (tok != 0)
或等效项。 完成此操作后,您也可以简化循环的主体;现在有两个多余的空性测试。