使用C中的循环内部的asprintf上的内存泄漏

时间:2015-09-16 05:02:01

标签: c memory-management memory-leaks

我有一段看起来像这样的代码

#include <stdio.h>
int main()
{
    int i;
    int number_of_chunks = 12;
    char *final_string = NULL;

    for(i = 0; i < number_of_chunks; i++) 
    {
        char *chunk = some_hash_table.pop(i);
        asprintf(&final_string, "%s%s", (final_string==NULL?"":final_string), chunk);
    }
    free(final_string);
    return 0;
}

这里我动态地整理字符串块,这意味着我事先并不知道每个块的大小。为此,我使用asprintf。代码工作正常,但会引起一些严重的内存问题。我怀疑是asprintf在每次迭代中分配内存,代码在每次迭代中丢失指针。如果还有其他任何方法我可以在循环中连接字符串,请指导我

2 个答案:

答案 0 :(得分:3)

以最简单的方式提出您的问题,您基本上尝试使用上述代码是什么 1.连续地将记忆分配给指针(在你的情况下,在for循环中12次)和
2.最后只将它释放一次,这会导致内存泄漏。

如下面的代码

#include <stdio.h>
int main()
{
    int i;
    int number_of_chunks = 12;
    char *final_string = NULL;

    for(i = 0; i < number_of_chunks; i++) 
    {
        /*For example: similar to what asprintf does, allocate memory to the pointer*/
        final_string = malloc(1);
    }
    free(final_string);
    return 0;
}

从上面的示例可以看出,您已经分配了内存12次,但只释放了一次。

代码段:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{  
    int i;
    int number_of_chunks = 12;
    char *final_string = NULL;
    char *tmp = NULL;

    for(i = 0; i < number_of_chunks; i++)
    {
        char *chunk = some_hash_table.pop(i);
        asprintf(&final_string, "%s%s", (tmp==NULL?"":tmp), chunk);
        if (tmp)
            free(tmp);
        tmp = final_string;
    }

    printf("%s\n", final_string);
    free(final_string);
    return 0;
}

答案 1 :(得分:1)

其他人已经指出你丢失了对除了最后一个分配以外的所有引用的引用,并且具有写为printf参数的相同字符串可能是未定义的行为,更可能发生重新分配并使格式参数无效。

您没有使用asprintf的格式化功能,您只能将其用于连接字符串,因此您可能需要采用其他方法。您可以收集数组中的字符串,确定所需的长度,根据需要进行分配,并使用memcpy填充分配的缓冲区。

或者你可以写一个类似于C ++&#39; s std::stringstream的自分配字符串缓冲区,例如:

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

struct append_t {
    char *str;          /* string */
    size_t len;         /* length of string */
    size_t size;        /* allocated size */
};

void append(struct append_t *app, const char *str)
{
    size_t len = strlen(str);

    while (app->len + len + 1 >= app->size) {
        app->size = app->size ? app->size * 2 : 0x100;
        app->str = realloc(app->str, app->size);
        /* error handling on NULL re-allocation */
    }

    strcpy(app->str + app->len, str);
    app->len += len;
}

int main(int argc, char **argv)
{
    struct append_t app = {NULL};

    for (int i = 1; i < argc; i++) {
        append(&app, argv[i]);
    }

    if (app.str) puts(app.str);

    free(app.str);
    return 0;
}