我无法弄清楚我在这里做错了什么。一般来说是valgrind和C的新手,但已设法清理除了这个之外的所有内存泄漏
==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);
}
}
答案 0 :(得分:3)
在tokenize()
中调用load_data()
的代码似乎负责执行释放。您将分配的空间返回给调用函数。
现在问题中显示了额外的代码,您需要在处理令牌的free(tokens);
循环之后添加for
。以下代码使用来自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)
或同等的。完成后,您可以简化循环体;现在有两个零冗余测试。