免费问题后重新分配(“realloc:无效的下一个大小”)

时间:2011-04-27 12:30:03

标签: c memory-leaks memory-management dynamic-memory-allocation

我对realloc有一个奇怪的问题,这是我的代码(只是相关部分,太大而不能在这里发布完整代码):

char * print_bar(struct bar *ptr) {
    char *buf = NULL;
    char *buftmp = NULL;
    size_t size = 60;
    int count = 0;

    if (ptr) {
        while (count == 0 || count+4 >= size) {
            buftmp = (char *) realloc((void *) buf, size * sizeof (char));
            if (buftmp == NULL) {
                if (buf != NULL) free(buf);
                exit(EXIT_FAILURE);
            }
            buf = buftmp;

            count = snprintf(buf, size, "%04d-%02d-%02d\t%02d:%02d:00\t%d\t%.2f\t%.2f\t%.2f\t%.2f\t%d",
                    ptr->year,
                    ptr->month,
                    ptr->day,
                    ptr->hour,
                    ptr->minute,
                    ptr->timeframe,
                    ptr->open,
                    ptr->high,
                    ptr->low,
                    ptr->close,
                    ptr->volume
                    );

            size += 4;
        }
    }

    return buf;
}

char * print_historico(short timeframe) {
    struct barlist *tmp = get_barlist(timeframe);
    struct bar *ptr;
    char * result = NULL;
    char * resulttmp = NULL;
    char * buf;
    int len;

    if (tmp) {
        ptr = tmp->first;
        while (ptr) {
            buf = print_bar(ptr);
            len = (result != NULL) ? strlen(result)+strlen(buf)+1 : strlen(buf)+1;
            resulttmp = (char *)realloc((void *)result, len);
            if (resulttmp == NULL)
            {
                if (result != NULL) free(result);
                exit (EXIT_FAILURE);
            }
            result = resulttmp;
            strncat(result, buf, strlen(buf));

            free(buf);
            ptr = ptr->next;
        }
    }

    return result;
}

在我的主要功能中,我有以下循环:

for (i = 1; i <= 27; i++) {
    historico = print_historico(i);
    if (historico != NULL)
    {
        puts(historico);
        free(historico);
    }
}

如果我编译并运行它失败并带有“realloc():下一个大小无效:0x0000000001704f60”。如果我使用调试器运行,我看到它完成主循环的第一次迭代确定,释放'historico'变量。当它用i = 2执行“print_historico”时,它在“while(ptr)”循环的第二次迭代时失败。

我找不到理由,任何线索?我也尝试制作一个小程序来隔离问题,但我无法做到。

2 个答案:

答案 0 :(得分:1)

尝试使用valgrind来隔离可能的内存泄漏或误用。

或者继续尝试将破碎的代码提炼为可以发布的示例。

编辑:我认为while条件可能有问题:

while (count == 0 || count+4 >= size)

为什么不每次都打印出值并运行程序并看看它是什么样的?

答案 1 :(得分:1)

strncat(result, buf, strlen(buf));

这是一个问题。 (可能是您报告的问题的原因。)

发生第一次重新分配时,结果未初始化。你真的需要在第一个char位置加一个'\ 0'让strncat工作(可靠)。

resulttmp = (char *)realloc((void *)result, len);
        if (resulttmp == NULL)
        {
            if (result != NULL) free(result);
            exit (EXIT_FAILURE);
        }
if(result == NULL) *resulttmp = '\0' // YOU NEED THIS!! First time initialization.