释放后重新分配问题(“重新分配:下一个大小无效”)

发布于 2024-11-03 18:28:38 字数 2262 浏览 0 评论 0原文

我在 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)”循环的第二次迭代中失败。

我找不到原因,有线索吗?我还尝试制作一个小程序来隔离问题,但我做不到。

I've got a strange problem with realloc, here's my code (relevant parts only, too big to post the full code here):

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;
}

In my main function i've got the following loop:

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

If i compile and run it fails with "realloc(): invalid next size: 0x0000000001704f60". If i run with the debugger i see it finishes the first iteration of the main loop ok, freeing the 'historico' variable. When it executes "print_historico" with i=2 it fails on the second iteration of the "while(ptr)" loop.

I can't find a reason, any clue? I've also tried to make a small program to isolate the problem, but i wasn't able.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

喵星人汪星人 2024-11-10 18:28:38
strncat(result, buf, strlen(buf));

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

当第一次重新分配发生时,结果未初始化。您确实需要在第一个字符位置放置一个 '\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.
strncat(result, buf, strlen(buf));

This is a problem. (It might be the cause of the problem you are reporting having.)

When the first realloc occurs, the result is not initialized. You really need to put a '\0' in the first char position for the strncat to work (reliably).

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.
睫毛溺水了 2024-11-10 18:28:38

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

或者继续尝试将损坏的代码提炼成可以发布的示例。

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

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

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

Try using valgrind to isolate possible memory leaks or misuses.

Or keep trying to distill the broken code into an example you can post.

Edit: I think the while condition may be faulty:

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

Why don't you print out the values each time and run the program and see what it looks like?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文