什么是GLIBC免费/malloc/realloc无效的下一个大小/无效的指针错误以及如何修复它?

发布于 2025-01-28 17:06:48 字数 2005 浏览 3 评论 0原文

您很可能会看到这个问题,因为您的问题已被关闭,这是重复的。有关相关问题的中等完整列表,请参阅一长串可能的重复列表 -   c内存分配和超越界限在元堆栈溢出上。


示例问题

来自

free(): invalid next size (fast): 0x0000000001b86170

2163646 /

void concat(stringList *list) {
    char *res = (char*)malloc(sizeof(char*));

    strcpy(res, list->head->string);

    list->tmp = list->head->next;
    while (list->tmp != NULL) {
        strcat(res, ",");
        strcat(res, list->tmp->string);
        list->tmp = list->tmp->next;
    }

    printf("%s\n", res);
    free(res);
}

通用问题

运行我的程序时,我会看到这样的错误消息:

*** glibc detected *** ./a.out: free(): corrupted unsorted chunks: 0x12345678 ***

详细信息可以包含以下任何内容,*** GLIBC检测到***和程序名称,并且该消息为其次是十六进制地址(显示为0x12345678)和另一个***

  • free(free():损坏的未分类块:0x12345678
  • free(free(Free():快速):0x12345678
  • free():无效的下一个大小(正常):0x12345678
  • free(Free():无效指针:0x12345678
  • free()尺寸:0x12345678
  • malloc():损坏的未排序块:0x12345678
  • ):损坏的无分量块2:0x12345678
  • malloc ( 0x12345678
  • malloc():内存损坏(fast):0x12345678
  • malloc():smallbin double链接列表损坏:0x12345678
  • munmap_chunk() :0x12345678
  • realloc():无效的下一个尺寸(fast):0x12345678
  • realloc():无效旧大小(快速):0x12345678
  • :无效指针:0x12345678
  • 损坏的双连锁列表:0x12345678

在调用frobnicate()函数时发生这种情况。该功能怎么了?

You are most likely seeing this question because your question has been closed as a duplicate of this. For a moderately complete list of related questions, please see A long list of possible duplicates — C memory allocation and overrunning bounds on Meta Stack Overflow.


Example Question

From free char*: invalid next size (fast) asked by noobie on 2014-04-11.

I am freeing a char* after a concatenation process, but I receive this error:

free(): invalid next size (fast): 0x0000000001b86170

This is my code:

void concat(stringList *list) {
    char *res = (char*)malloc(sizeof(char*));

    strcpy(res, list->head->string);

    list->tmp = list->head->next;
    while (list->tmp != NULL) {
        strcat(res, ",");
        strcat(res, list->tmp->string);
        list->tmp = list->tmp->next;
    }

    printf("%s\n", res);
    free(res);
}

Generic Question

When running my program, I see an error message like this:

*** glibc detected *** ./a.out: free(): corrupted unsorted chunks: 0x12345678 ***

The detailed information can contain any of the following after the *** glibc detected *** and the program name, and the message is followed by a hexadecimal address (shown as 0x12345678) and another ***:

  • free(): corrupted unsorted chunks: 0x12345678
  • free(): invalid next size (fast): 0x12345678
  • free(): invalid next size (normal): 0x12345678
  • free(): invalid pointer: 0x12345678
  • free(): invalid size: 0x12345678
  • malloc(): corrupted unsorted chunks: 0x12345678
  • malloc(): corrupted unsorted chunks 2: 0x12345678
  • malloc(): memory corruption: 0x12345678
  • malloc(): memory corruption (fast): 0x12345678
  • malloc(): smallbin double linked list corrupted: 0x12345678
  • munmap_chunk(): invalid pointer: 0x12345678
  • realloc(): invalid next size (fast): 0x12345678
  • realloc(): invalid old size (fast): 0x12345678
  • realloc(): invalid pointer: 0x12345678
  • corrupted double-linked list: 0x12345678

This happens while calling the frobnicate() function; what is wrong with that function?

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

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

发布评论

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

评论(1

椒妓 2025-02-04 17:06:48

例如问题

Undind 给予了接受的答案示例问题:

您的代码错误。

您正在为单个指针(malloc(sizeof(char*)))分配空间,但没有字符。您正在用所有字符串覆盖分配的空间,从而导致不确定的行为(在这种情况下,损坏malloc()的书籍保存数据)。

您无需为指针分配空间(res);这是局部变量。您必须为您希望存储在指针持有的地址的所有字符分配空间。

由于您将要浏览列表以查找串联的字符串,因此您无法预先知道总尺寸。您将不得不在列表中进行两次通过:一个要概括每个字符串的strlen(),然后为分隔符和终结器分配该加上空间,然后在您实际使用时进行另一个通过串联。

通用答案

您看到的是GLIBC分配器内部结构腐败的结果。当您分配或释放动态内存时,分配器必须管理从操作系统保留的内存,并根据您要求的操作,找到一个新的块,将一个释放的零件分类到其中的列表中可以稍后再分发,或将内存还给操作系统。这些错误消息表明,它用于管理此功能的数据结构已损坏。

这些错误都意味着您的某些代码已经修改了未给予使用的内存,调用了 不确定的行为。这很可能是在程序中覆盖一些内存的结果,并且完全有可能错误在frobnicate()函数中。

是的,这意味着您使用的程序中的任何地方或第三方库中的任何地方都可以

对于堆栈溢出而言,这可能不是一个好问题。除非您对问题进行了很好的简单复制,否则该社区可能无法为您提供太多帮助。错误的原因可能在您的代码中的任何位置(并且通常不在发现错误的函数中),并且可能是我们看不到的代码。堆栈溢出是不是协作调试站点。即使有人可以在您的代码中找到缺陷,您的特定问题也不太可能对任何未来的访客有所帮助。

免费的原因

  • 免费使用后。您释放了/删除了一些记忆并随后写入其中,覆盖了簿记的结构。
  • 偏离n错误。您正在将n个字节撰写后,将n个字节分配给了Glibc内部用于簿记的未分配记忆。
  • 非初始化的指针。您没有初始化指针。巧合的是,它指出了GLIBC保留的某些内存,但不是由您的程序分配,而是您写信给它。
  • 分配错误的空间。这可能是因为您写了long *data = malloc(number *4)而不是long *data = malloc(number sizeof(long));或(更好)long *data = malloc(number *sizeof( *data));。还有许多其他方法可以使尺寸计算错误。另一个常见的是忘记在字符串结束时忘记为空终结者字符:char *copy = malloc(strlen(str));而不是char *copy *copy = malloc( strlen(str)+1);

您现在需要做的是卷起袖子并调试该问题

没有简单的答案要寻找什么或可以解决什么。您使用错误的单一句法结构。该错误的原因可能是数千种品种。

工具

  • valgrind 一种工具主要是为了找到准确的错误而创建的工具。如果找不到任何东西,请确保您正在使用最新版本,并且您还尝试了随附的exp-sgcheck工具。如果您正在运行多线程代码,则原因也可能与种族条件有关,因此您可能需要尝试纳入的种族条件检查器drdhelgrind以获取更多见解。在撰写本文时,Valgrind支持以下平台:
    • x86/linux,
    • AMD64/Linux,
    • ARM/Linux,
    • ppc32/linux,
    • ppc64/linux,
    • s390x/linux,
    • mips32/linux,
    • mips64/linux,
    • ARM/ANDROID(2.3.x及以后),
    • x86/android(4.0及以后),
    • x86/darwin和
    • AMD64/Darwin(Mac OS X 10.7,对10.8的支持有限)。
  • purify 类似的工具瓦尔格林德,但商业目的是针对不同的平台。
  • addresssanitizer 类似的工具,但集成到编译器工具座上(GCC和Clang)。
  • efence 分配替换的下降,该替换会试图早些时候崩溃您的程序,这样您就可以通过普通的调试器找到写入为无效的内存的地方。
  • dmalloc 一个与efence相似的库。

需要更多的帮助

如果您无法使用这些工具解决问题,则 和可验证的示例?)或等效地,sscce(简短,自我包含,正确(可编译),示例< /a>)。

请记住要处理代码的副本,因为创建MCVE需要您残酷地删除无助于复制问题的代码。使用VCS(版本控制系统)协助是一个好主意。您可以记录中间阶段,以最少将问题减少。它可能是一个新的抛弃存储库,仅将您的问题降低到可管理的规模。

通过对您的代码进行良好的模块化设计,创建MCVE应该相对容易。也许您还已经进行了一个单位测试,该测试更适合被送入上述工具之一。您可能还想创建一个可以作为此错误的回归测试来创建一个。

Answer for Example Question

unwind gave the accepted answer to the example question:

Your code is wrong.

You are allocating space for a single pointer (malloc(sizeof(char*))), but no characters. You are overwriting your allocated space with all the strings, causing undefined behavior (in this particular case, corrupting malloc()'s book-keeping data).

You don't need to allocate space for the pointer (res); it's a local variable. You must allocate space for all the characters you wish to store at the address held by the pointer.

Since you're going to be traversing a list to find strings to concatenate, you can't know the total size upfront. You're going to have to do two passes over the list: one to sum the strlen() of each string, then allocate that plus space for the separator and terminator, then another pass when you actually do the concatenation.

Generic Answer

What you are seeing is the result of a corruption in the internal structures of the glibc allocator. When you are allocating or freeing dynamic memory, the allocator has to manage the memory it reserved from the OS and, depending on the action requested by you, find a new chunk to hand out, sort a freed chunk into the list of those that it can hand out later again, or give the memory back to the operating system. These error messages show that the data structures it uses to manage this functionality are corrupted.

These errors all mean that some of your code has modified memory that it was not given to use, invoking undefined behaviour. This is most likely the result of overwriting some memory quite a bit earlier in your program, and it is totally possible that the error does not lie in the frobnicate() function.

Yes, this means that the error can be anywhere in your program or 3rd party libraries you use.

This is probably not a good question for Stack Overflow. Unless you have a good simple reproduction of your problem, this community may be unable to help you very much. The cause of the error can be anywhere in your code (and is very often not in the function where the error is spotted), and it may be in code that we cannot see. Stack Overflow is not a collaborative debugging site. Even when someone can find the flaw in your code, it is unlikely that your specific question will ever help any future visitor.

Common causes

  • Use after free. You have freed/deleted some memory and writing into it afterwards, overwriting the structures glibc needs for bookkeeping.
  • Off-by-N error. You are writing N bytes after an allocated chunk into unallocated memory that glibc uses internally for its bookkeeping.
  • Uninitialized pointers. You are not initializing a pointer. By coincidence it points to some memory reserved by glibc but not allocated by your program and you write to it.
  • Allocating the wrong amount of space. This can be because you wrote long *data = malloc(number * 4) instead of long *data = malloc(number * sizeof(long)); or (better) long *data = malloc(number * sizeof(*data));. There are many other ways to get the size calculation wrong. Another common one is to forget to account for the null terminator character at the end of a string: char *copy = malloc(strlen(str)); instead of char *copy = malloc(strlen(str)+1);.

What you need to do now is to roll up your sleeves and debug that problem

There is no simple answer what to look for, or what to fix. No single syntactical construct that you were using wrong. The cause of this bug can come in literally thousands of varieties.

Tools

  • valgrind A tool created mostly for the purpose of finding exactly this kinds of errors. If it can't find anything make sure you are using the latest version, and you are also trying out the included exp-sgcheck tool. If you are running multithreaded code, the cause might also be related to a race condition so you might want to try the included race condition checkers drd and helgrind for more insight. At the point of writing this, valgrind supports the following platforms:
    • X86/Linux,
    • AMD64/Linux,
    • ARM/Linux,
    • PPC32/Linux,
    • PPC64/Linux,
    • S390X/Linux,
    • MIPS32/Linux,
    • MIPS64/Linux,
    • ARM/Android (2.3.x and later),
    • X86/Android (4.0 and later),
    • X86/Darwin and
    • AMD64/Darwin (Mac OS X 10.7, with limited support for 10.8).
  • purify A similar tool to valgrind, but commercial and aimed at a different set of platforms.
  • AddressSanitizer A similar tool, but integrated into the compiler toolchain (gcc and clang).
  • efence A drop in allocator replacement that will try to crash your program earlier, so that you can find out with a normal debugger where the write to invalid memory happened.
  • dmalloc a library with a similar purpose as efence.

Needing more assistance

If you can't solve your problem using one these tools, you should try to create an MCVE (How to create a Minimal, Complete, and Verifiable Example?) or, equivalently, an SSCCE (Short, Self Contained, Correct (Compilable), Example).

Remember to work on a copy of your code because creating an MCVE requires you to ruthlessly remove code that does not help reproduce the problem. Using a VCS (version control system) to assist is a good idea; you can record intermediate stages in reducing the problem to a minimum. It might be a new throw-away repository just for reducing your problem to a manageable size.

With a good modular design to your code, it should be relatively easy to create the MCVE. Maybe you also already have a unit test that is better suited to be fed into one of the above tools. You also might just want to create one that can later serve as a regression test for this bug.

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