c - 小 C 程序产生 500 多个 malloc?

标签 c macos malloc valgrind

我学习 C 一段时间了,正在为一个项目编写 C 代码。我主要尝试测试结构体的用法。我为它编写了一个简单的创建和删除方法:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct TokenizerT_ {
  int index;
};

typedef struct TokenizerT_ TokenizerT;

TokenizerT *TKCreate( char * ts ) {
  TokenizerT *tk = (TokenizerT *)(malloc(sizeof(TokenizerT)));

  if(tk == NULL)
    return NULL;

  tk->index = 0;

  return tk;
}

void TKDestroy( TokenizerT * tk ) {
  free(tk);
  return;
}

int main(int argc, char ** argv)
{
    TokenizerT *tk = TKCreate(argv[1]);
    printf("%lu\n", sizeof(tk->index));
    TKDestroy(tk);
    return 0;
}

因此,这会在我的机器上按预期编译并打印 4。然而,当我通过 valgrind 运行它时,我得到了这个:

==816== Memcheck, a memory error detector
==816== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==816== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==816== Command: ./test
==816== 
--816-- run: /usr/bin/dsymutil "./test"
warning: no debug symbols in executable (-arch x86_64)
4
==816== 
==816== HEAP SUMMARY:
==816==     in use at exit: 38,504 bytes in 415 blocks
==816==   total heap usage: 516 allocs, 101 frees, 45,484 bytes allocated
==816== 
==816== LEAK SUMMARY:
==816==    definitely lost: 0 bytes in 0 blocks
==816==    indirectly lost: 0 bytes in 0 blocks
==816==      possibly lost: 0 bytes in 0 blocks
==816==    still reachable: 0 bytes in 0 blocks
==816==         suppressed: 38,504 bytes in 415 blocks
==816== 
==816== For counts of detected and suppressed errors, rerun with: -v
==816== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

我不知道这是否有帮助,但我的机器是 OSX 10.10.5。我真的不知道我的程序如何创建 501 个 malloc。

最佳答案

这不是你的代码;这是泄漏的启动代码。对您来说至关重要的信息是:

==816== LEAK SUMMARY:
==816==    definitely lost: 0 bytes in 0 blocks
==816==    indirectly lost: 0 bytes in 0 blocks
==816==      possibly lost: 0 bytes in 0 blocks
==816==    still reachable: 0 bytes in 0 blocks
==816==         suppressed: 38,504 bytes in 415 blocks

尤其是最后一行。我正在使用具有相同版本号的 Valgrind 版本,但几乎可以肯定要旧得多,并且我不得不添加一大堆抑制。其他人似乎已经为您完成了。

所以,不用担心 - Mac OS X 上有一堆“正在使用”或“抑制”内存是正常的。

当我运行你的代码的这个轻度黑客版本时:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct TokenizerT_ {
  int index;
};

typedef struct TokenizerT_ TokenizerT;

TokenizerT *TKCreate( char * ts );
TokenizerT *TKCreate( char * ts ) {
  TokenizerT *tk = (TokenizerT *)(malloc(sizeof(TokenizerT)));

  if(tk == NULL)
    return NULL;

  tk->index = strlen(ts);

  return tk;
}

void TKDestroy( TokenizerT * tk );
void TKDestroy( TokenizerT * tk ) {
  free(tk);
  return;
}

int main(int argc, char ** argv)
{
    TokenizerT *tk = TKCreate(argc > 1 ? argv[1] : "CogentConniptions");
    printf("%lu\n", sizeof(tk->index));
    TKDestroy(tk);
    return 0;
}

为了避免在我的默认编译选项下出现编译警告,这些技巧是必要的:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition -Werror vg.c -o vg
$

当我运行它时,我得到:

$ valgrind vg
==31534== Memcheck, a memory error detector
==31534== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==31534== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==31534== Command: vg
==31534== 
--31534-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option
--31534-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)
--31534-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)
4
==31534== 
==31534== HEAP SUMMARY:
==31534==     in use at exit: 38,874 bytes in 418 blocks
==31534==   total heap usage: 519 allocs, 101 frees, 45,854 bytes allocated
==31534== 
==31534== LEAK SUMMARY:
==31534==    definitely lost: 16 bytes in 1 blocks
==31534==    indirectly lost: 0 bytes in 0 blocks
==31534==      possibly lost: 13,002 bytes in 109 blocks
==31534==    still reachable: 25,856 bytes in 308 blocks
==31534==         suppressed: 0 bytes in 0 blocks
==31534== Rerun with --leak-check=full to see details of leaked memory
==31534== 
==31534== For counts of detected and suppressed errors, rerun with: -v
==31534== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$

还有我手工制作的抑制文件:

$ valgrind --suppressions=suppressions vg
==31538== Memcheck, a memory error detector
==31538== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==31538== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==31538== Command: vg
==31538== 
--31538-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option
--31538-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)
--31538-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)
4
==31538== 
==31538== HEAP SUMMARY:
==31538==     in use at exit: 38,874 bytes in 418 blocks
==31538==   total heap usage: 519 allocs, 101 frees, 45,854 bytes allocated
==31538== 
==31538== LEAK SUMMARY:
==31538==    definitely lost: 0 bytes in 0 blocks
==31538==    indirectly lost: 0 bytes in 0 blocks
==31538==      possibly lost: 0 bytes in 0 blocks
==31538==    still reachable: 25,856 bytes in 308 blocks
==31538==         suppressed: 13,018 bytes in 110 blocks
==31538== Rerun with --leak-check=full to see details of leaked memory
==31538== 
==31538== For counts of detected and suppressed errors, rerun with: -v
==31538== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$

您内置的抑制文件比我的做得更好。

关于c - 小 C 程序产生 500 多个 malloc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32663824/

相关文章:

objective-c - HUD 窗口留在应用程序内? Xcode

c++ - 是否有某种工具或助手可以将 MFC/C++ 应用程序移植到 OS X/Cocoa?

c - VLA 和通过 malloc 进行动态内存分配有什么区别?

c - 在 C 中进行清理的另一种方法?

c - OS X 上 C 标准库的线程安全

c - 嵌套的 for 循环 < 运算符不应该工作

c - 寻找用 C 实现的快速排序整数数组交集/union 算法

c++ - 从另一个进程在用户模式下回调,没有额外的线程

c - 获取分配的内存空间的特定长度的一部分

c - 如何使用C程序在ubuntu中永久设置时区