使用语言 c 时在 .h 和 .c 中 malloc 和 free

malloc and free in .h and .c while using language c

我是 C 编程的新手,我对 malloc()free() 感到很困惑。

我需要从文件 (.yaml) 中读取一些随机数的随机数据值并将它们存储在 hashmap 中,类似于 < char *key_name, char *type, void *value >

我正在使用 void * 指针来存储我读取为 char * 的任何类型数据,因此我想编写自己的函数来确定数据类型和 return大小合适的指针以将其传递给进一步的任务。

我希望这个函数在我的小解析器(myparser.h 和 myparser.c)中,以便将来将其用作库。

但是!例如,我在 myparser.c 中为读取的每个浮点值执行 中的这段代码:

void *parser_get_pointer(char *token_value, char *type) {
...    
else if (strcmp(type, "float") == 0) {
    printf("Type float recognized\n");

    float *fp = (float *)malloc(sizeof(float));
    *fp = atof(token_value);

    void *result = (float *)malloc(sizeof(float));
    result = fp;


     return (float *)result;
    }
...
}

主要问题是我应该在哪里 free(fp) 这样我就不会丢失 main.c 中的数据?

不要做两次malloc,会导致内存泄露

完成atof后只需return fp,不需要结果指针。

您可以将 fp 存储在 hashmap 中,并在释放 hashmap 时释放它。

1.You 可能根本不需要 malloc()。只需使用:

static float f;
if (strcmp(type, "float")==0) {
    f = atof(token_value);
    return (void *)&f;
}
  1. 请注意,由于您的函数 returns (void *),调用者将获得值但不知道大小。

  2. 您的代码存在内存泄漏;您为 'result' 分配 space,然后当您分配 'result' 内存 space 分配给 'fp' 时 space 丢失(通过 'result = fp'

  3. 如果您真的想保持代码不变,那么: 一种。删除行 'void *result = (float *)malloc(sizeof(float)); b.表明函数的调用者必须释放它,即

    ptr = (浮动 *)parser_get_pointer(...) printf("value = %f\n", ptr); 免费(指针);

希望对您有所帮助。

关于malloc()[的一些普遍接受的想法 =47=]、calloc()realloc()函数使用:

1)在使用C时不要强制转换这些函数的return

int *a = (int)malloc(10*sizeof(int)); //wrong
int *a = malloc(10*sizeof(int)); //correct 

2) 检查函数

的 return 值
int *a = malloc(10*sizeof(int));
a[0] = 10; //wrong - if malloc failed, a will be  NULL.

int *a = malloc(10*sizeof(int));
if(a)
{
    a[0] = 10; //correct 

3) 在 realloc() 的情况下使用 tmp 变量来避免内存泄漏

tmp = realloc(orig, newsize);
if (tmp == NULL)
{
    // could not realloc, but orig still valid
}
else
{
    orig = tmp;
}

4) 每次调用 [c] 总是调用一次 free() [m][re]alloc()

int *a = malloc(10*sizeof(int));
if(a)
{
    a[0] = 10; //correct
    ...
    free(a);  
}
else
{
     //handle error
}

不这样做导致内存泄漏。

让我们解决一些具体问题:

首先,下面的代码是不必要的并且它引入了内存泄漏:

void *result = (float *)malloc(sizeof(float));
result = fp;

您将 malloc 调用的结果分配给 result,然后立即用 fp 覆盖该值。因此,您丢失了从 malloc 编辑的指针值 return,这意味着您以后将无法 free 该内存。您不需要留出额外的内存来存储指针值。

这段代码的写法,根本不需要result变量;只是 return fp

其次,不要强制转换 malloc1 的结果 - 根据 C89 标准,它是不必要的,并且在 C89 编译器下,它可以抑制有用的诊断。编写 malloc 调用的最干净的方法是

 T *p = malloc( N * sizeof *p ); // for any type T

 T *p;
 ...
 p = malloc( N * sizeof *p );

表达式 *p 的类型是 T,因此 sizeof *p 给出与 sizeof (T) 相同的结果。 sizeof 运算符不会尝试评估参数;它不会尝试取消引用 p

也不需要强制转换return值;在 C 中,任何指针类型的值都可以转换为 void * 并再次返回,而无需显式强制转换。

至于将 free 调用放在哪里,那将是您决定不再需要存储指向的值的任何地方(例如从哈希图中删除该项目)。那将在您发布的代码之外的某个地方。


1。 C++ 确实 需要强制转换,因为 C++ 不允许 void * 和其他指针类型之间的隐式转换,但如果您使用的是 C++,您就不会乱用 naked无论如何指针。