【发布时间】:2015-10-05 04:08:03
【问题描述】:
我创建了一个简单的程序,它使用线程解析日志文件并打印一个值。在阅读了creating detached threads 之后,我在我的主函数中使线程分离并销毁了属性(PTHREAD_CREATE_DETACHED)。我还退出了线程(不退出会造成更多的内存泄漏)。但是,我仍然有内存泄漏和错误,即使我很确定我不会在程序的其余部分中 malloc 任何东西。完整代码如下:
*感谢 Jonathan Leffler 解析分隔字符串的 strtok_fixed 函数
static char *strtok_fixed(char *str, char const *delims)
{
static char *src = NULL;
char *p, *ret = 0;
if (str != NULL)
src = str;
if (src == NULL || *src == '\0') // Fix 1
return NULL;
ret = src; // Fix 2
if ((p = strpbrk(src, delims)) != NULL)
{
*p = 0;
//ret = src; // Unnecessary
src = ++p;
}
else
src += strlen(src);
return ret;
}
void * parse_log(void *arguments){
file = fopen("oms_requests.log", "r");
char c;
if (file == NULL){ //no valid file
printf("couldn't find the file\n");
} else {
int f = fseek(file, -2, SEEK_END);
if (f == 0){
int counter = 1;
c = fgetc(file);
while (c != '\n'){
counter++;
fseek(file, -counter, SEEK_END);
c = fgetc(file);
}
//now read last line in the log into buff
char buff[counter];
int l = fread(buff, 1, counter, file);
buff[counter-1] = '\0';
if (l != counter-1){
printf("counter is wrong\n");
} else {
//skip over 22 commas to get the value that I want
char *buffer = strtok_fixed(buff, ",");
for (int i = 0; i < 22; i++){
buffer = strtok_fixed(NULL, ",");
if (buffer == '\0') i++;
printf("%s\n", buffer);
}
printf("%ld\n", strtol(buffer, NULL, 10));
}
} else {
printf("error in getting to bottom of file\n");
}
}
fclose(file);
}
int main(int argc, char *argv[])
{
//create pthread attributes and set to detached
pthread_t thr;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int l = pthread_create(&thr, &attr, parse_log, NULL);
if (l != 0){
printf("Didn't work\n");
return -1;
}
//destroy pthread attribute and exit
pthread_attr_destroy(&attr);
pthread_exit(&thr);
return 0;
}
这是我运行程序时 valgrind 给出的报告:
==12387== HEAP SUMMARY:
==12387== in use at exit: 272 bytes in 1 blocks
==12387== total heap usage: 7 allocs, 6 frees, 2,510 bytes allocated
==12387==
==12387== Searching for pointers to 1 not-freed blocks
==12387== Checked 8,486,312 bytes
==12387==
==12387== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1
==12387== at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12387== by 0x4012E54: _dl_allocate_tls (dl-tls.c:296)
==12387== by 0x4E3FDA0: pthread_create@@GLIBC_2.2.5 (allocatestack.c:589)
==12387== by 0x400E11: main (in /afs/.ir.stanford.edu/users/d/i/dianale/CS107/assign1a/reassemble)
==12387==
==12387== LEAK SUMMARY:
==12387== definitely lost: 0 bytes in 0 blocks
==12387== indirectly lost: 0 bytes in 0 blocks
==12387== possibly lost: 272 bytes in 1 blocks
==12387== still reachable: 0 bytes in 0 blocks
==12387== suppressed: 0 bytes in 0 blocks
==12387==
==12387== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
我也尝试过 pthread_detach(&thr) 而不是设置属性(我也尝试过同时拥有两者),但我仍然遇到完全相同的内存泄漏和错误。有没有什么办法解决这一问题?
【问题讨论】:
-
你如何编译这个?您使用 gcc 选项
-pthread还是使用-lpthread的“just”链接?? -
在
thr这里传递pthread_exit(&thr);背后的想法是什么? -
我在编译时专门在命令行中写了
gcc -pthread -std=c99 -o file file.c,我没有收到任何错误或警告。我还认为我需要在pthread_exit中指定要退出的确切线程,所以我将 &thr 放在那里。我也尝试过pthread_exit(NULL)并得到完全相同的内存错误/泄漏。 -
总是在所有警告打开的情况下编译。为此,请使用 gcc 指定
-Wall -Wextra -pedantic。此外,您可能想查看pthread_exit()的文档以了解该参数的用途。猜测是一个糟糕的选择......真的。 -
感谢您提供有关警告的提示!我摆脱了所有警告,并且阅读了 pthread_exit() 文档。根据我的理解,在我的 parse_log 函数底部添加
return NULL应该在 thr 上隐式调用 pthread_exit() 并结束线程。我认为 pthread_exit 应该在您可能有一个线程等待子线程的状态时使用,并且 pthread_exit 结束子线程,使其可供父线程使用。所以,我添加了return NULL并删除了pthread_exit(),但我得到了更多的泄漏。我是不是误会了什么?
标签: c memory memory-management memory-leaks pthreads