【问题标题】:Error: free(): invalid next size (fast):错误:free():下一个大小无效(快速):
【发布时间】:2011-01-18 21:44:35
【问题描述】:

我遇到的这个奇怪的错误是什么?我在 Ubuntu 10.10 上使用 g++ 编译 C++。它在我运行可执行文件时随机弹出(可能在 8 小时内 2 次,每小时编译 10 次)。但是,如果我 make clean 并重新编译,它大部分时间都会消失。

*** glibc detected *** ./emailQueue.app: free(): invalid next size (fast): 0x0000000001c40270 ***
======= Backtrace: =========
/lib/libc.so.6(+0x774b6)[0x7f490d95e4b6]
/lib/libc.so.6(cfree+0x73)[0x7f490d964c83]
./emailQueue.app[0x401f47]
/lib/libc.so.6(__libc_start_main+0xfe)[0x7f490d905d8e]
./emailQueue.app[0x401cc9]
======= Memory map: ========
00400000-0040d000 r-xp 00000000 08:01 1311132                            /home/server/Projects/email/emailQueue.app
0060d000-0060e000 r--p 0000d000 08:01 1311132                            /home/server/Projects/email/emailQueue.app
0060e000-0060f000 rw-p 0000e000 08:01 1311132                            /home/server/Projects/email/emailQueue.app
01c40000-01c82000 rw-p 00000000 00:00 0                                  [heap]
7f4908000000-7f4908021000 rw-p 00000000 00:00 0 
7f4908021000-7f490c000000 ---p 00000000 00:00 0 
7f490ce52000-7f490ce5e000 r-xp 00000000 08:01 1051251                    /lib/libnss_files-2.12.1.so
7f490ce5e000-7f490d05d000 ---p 0000c000 08:01 1051251                    /lib/libnss_files-2.12.1.so
7f490d05d000-7f490d05e000 r--p 0000b000 08:01 1051251                    /lib/libnss_files-2.12.1.so
7f490d05e000-7f490d05f000 rw-p 0000c000 08:01 1051251                    /lib/libnss_files-2.12.1.so
7f490d05f000-7f490d075000 r-xp 00000000 08:01 1048770                    /lib/libz.so.1.2.3.4
7f490d075000-7f490d275000 ---p 00016000 08:01 1048770                    /lib/libz.so.1.2.3.4
7f490d275000-7f490d276000 r--p 00016000 08:01 1048770                    /lib/libz.so.1.2.3.4
7f490d276000-7f490d277000 rw-p 00017000 08:01 1048770                    /lib/libz.so.1.2.3.4
7f490d277000-7f490d28e000 r-xp 00000000 08:01 1051248                    /lib/libnsl-2.12.1.so
7f490d28e000-7f490d48d000 ---p 00017000 08:01 1051248                    /lib/libnsl-2.12.1.so
7f490d48d000-7f490d48e000 r--p 00016000 08:01 1051248                    /lib/libnsl-2.12.1.so
7f490d48e000-7f490d48f000 rw-p 00017000 08:01 1051248                    /lib/libnsl-2.12.1.so
7f490d48f000-7f490d491000 rw-p 00000000 00:00 0 
7f490d491000-7f490d49a000 r-xp 00000000 08:01 1051244                    /lib/libcrypt-2.12.1.so
7f490d49a000-7f490d69a000 ---p 00009000 08:01 1051244                    /lib/libcrypt-2.12.1.so
7f490d69a000-7f490d69b000 r--p 00009000 08:01 1051244                    /lib/libcrypt-2.12.1.so
7f490d69b000-7f490d69c000 rw-p 0000a000 08:01 1051244                    /lib/libcrypt-2.12.1.so
7f490d69c000-7f490d6ca000 rw-p 00000000 00:00 0 
7f490d6ca000-7f490d6e2000 r-xp 00000000 08:01 1051256                    /lib/libpthread-2.12.1.so
7f490d6e2000-7f490d8e1000 ---p 00018000 08:01 1051256                    /lib/libpthread-2.12.1.so
7f490d8e1000-7f490d8e2000 r--p 00017000 08:01 1051256                    /lib/libpthread-2.12.1.so
7f490d8e2000-7f490d8e3000 rw-p 00018000 08:01 1051256                    /lib/libpthread-2.12.1.so
7f490d8e3000-7f490d8e7000 rw-p 00000000 00:00 0 
7f490d8e7000-7f490da61000 r-xp 00000000 08:01 1048743                    /lib/libc-2.12.1.so
7f490da61000-7f490dc60000 ---p 0017a000 08:01 1048743                    /lib/libc-2.12.1.so
7f490dc60000-7f490dc64000 r--p 00179000 08:01 1048743                    /lib/libc-2.12.1.so
7f490dc64000-7f490dc65000 rw-p 0017d000 08:01 1048743                    /lib/libc-2.12.1.so
7f490dc65000-7f490dc6a000 rw-p 00000000 00:00 0 
7f490dc6a000-7f490dc7f000 r-xp 00000000 08:01 1048655                    /lib/libgcc_s.so.1
7f490dc7f000-7f490de7e000 ---p 00015000 08:01 1048655                    /lib/libgcc_s.so.1
7f490de7e000-7f490de7f000 r--p 00014000 08:01 1048655                    /lib/libgcc_s.so.1
7f490de7f000-7f490de80000 rw-p 00015000 08:01 1048655                    /lib/libgcc_s.so.1
7f490de80000-7f490df02000 r-xp 00000000 08:01 1051246                    /lib/libm-2.12.1.so
7f490df02000-7f490e101000 ---p 00082000 08:01 1051246                    /lib/libm-2.12.1.so
7f490e101000-7f490e102000 r--p 00081000 08:01 1051246                    /lib/libm-2.12.1.so
7f490e102000-7f490e103000 rw-p 00082000 08:01 1051246                    /lib/libm-2.12.1.so
7f490e103000-7f490e1eb000 r-xp 00000000 08:01 4853329                    /usr/lib/libstdc++.so.6.0.14
7f490e1eb000-7f490e3ea000 ---p 000e8000 08:01 4853329                    /usr/lib/libstdc++.so.6.0.14
7f490e3ea000-7f490e3f2000 r--p 000e7000 08:01 4853329                    /usr/lib/libstdc++.so.6.0.14
7f490e3f2000-7f490e3f4000 rw-p 000ef000 08:01 4853329                    /usr/lib/libstdc++.so.6.0.14
7f490e3f4000-7f490e409000 rw-p 00000000 00:00 0 
7f490e409000-7f490e5c7000 r-xp 00000000 08:01 4851315                    /usr/lib/libmysqlclient.so.16.0.0
7f490e5c7000-7f490e7c7000 ---p 001be000 08:01 4851315                    /usr/lib/libmysqlclient.so.16.0.0
7f490e7c7000-7f490e7cc000 r--p 001be000 08:01 4851315                    /usr/lib/libmysqlclient.so.16.0.0
7f490e7cc000-7f490e816000 rw-p 001c3000 08:01 4851315                    /usr/lib/libmysqlclient.so.16.0.0
7f490e816000-7f490e817000 rw-p 00000000 00:00 0 
7f490e817000-7f490e837000 r-xp 00000000 08:01 1048597                    /lib/ld-2.12.1.so
7f490ea15000-7f490ea1c000 rw-p 00000000 00:00 0 
7f490ea33000-7f490ea37000 rw-p 00000000 00:00 0 
7f490ea37000-7f490ea38000 r--p 00020000 08:01 1048597                    /lib/ld-2.12.1.so
7f490ea38000-7f490ea39000 rw-p 00021000 08:01 1048597                    /lib/ld-2.12.1.so
7f490ea39000-7f490ea3a000 rw-p 00000000 00:00 0 
7fffb85b9000-7fffb85da000 rw-p 00000000 00:00 0                          [stack]
7fffb85ff000-7fffb8600000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

【问题讨论】:

  • 缺少分号导致我出现此错误。

标签: c++ g++


【解决方案1】:

这意味着你有一个内存错误。您可能正在尝试 free 不是由 malloc 分配的指针(或 delete 不是由 new 创建的对象)或者您可能正在尝试 free/delete 这样一个对象不止一次。您可能正在溢出缓冲区或以其他方式写入不应写入的内存,从而导致堆损坏。

任何数量的编程错误都可能导致此问题。您需要使用调试器,获取回溯,并查看发生错误时程序在做什么。如果失败并且您确定您在之前的某个时间点损坏了堆,那么您可能会进行一些痛苦的调试(如果项目足够小以至于您可以逐个处理它可能不会太痛苦)。

【讨论】:

  • 类似 valgrind 的工具在查找此类错误的根源时非常有用。只需确保使用调试符号进行编译即可。
  • 仅供参考:我在调整 std::vector 的大小后发生了这种情况,但它不够大。
  • 真的吗?当向量不够大时,free() 会出现问题。至少要先阅读问题。
【解决方案2】:

我遇到了同样的问题,尽管我没有在我的程序中进行任何动态内存分配,但是我访问了一个向量的索引而没有为其分配内存。 所以,如果同样的情况,最好使用resize()分配一些内存,然后访问向量元素。

【讨论】:

    【解决方案3】:

    我们需要代码,但是当您尝试从未分配的指针free() 内存时,通常会弹出该代码。这通常发生在您进行双重释放时。

    【讨论】:

      【解决方案4】:

      如果您试图为指针数组分配空间,例如

      char** my_array_of_strings;  // or some array of pointers such as int** or even void**
      

      那么在为 n 个指针分配空间时,您将需要考虑字长(64 位系统中为 8 个字节,32 位系统中为 4 个字节)。指针的大小与您的字长相同。

      因此,虽然您可能希望为 n 个指针分配空间,但实际上您需要 n 乘以 8 或 4(分别适用于 64 位或 32 位系统)

      为避免为 8 个字节的 n 个元素溢出分配的内存:

      my_array_of_strings = (char**) malloc( n * 8 );  // for 64-bit systems
      my_array_of_strings = (char**) malloc( n * 4 );  // for 32-bit systems
      

      这将返回一个包含 n 个指针的块,每个指针包含 8 个字节(如果您使用的是 32 位系统,则为 4 个字节)

      我注意到,当您没有补偿字长时,Linux 将允许您使用所有 n 指针,但是当您尝试释放该内存时,它意识到它的错误并给出了那个相当讨厌的错误。而且这是一个糟糕的问题,当您溢出分配的内存时,许多安全问题都在等待。

      【讨论】:

      • 我们可以通过使用sizeof(char*)而不是硬编码4或8字节来使相同的代码通用任何系统。
      • 在使用malloc的时候不使用sizeof操作符真的是自找麻烦。 IIRC 标准保证了字符的大小,但几乎所有其他内容都取决于 ISA,所以你最好在任何地方使用sizeof
      【解决方案5】:

      我遇到过这样一种情况,当有人调整它的大小时,代码会绕过 STL 的 api 并不安全地写入数组。在此处添加断言抓住了它:

      void Logo::add(const QVector3D &v, const QVector3D &n)
      {
       GLfloat *p = m_data.data() + m_count;
       *p++ = v.x();
       *p++ = v.y();
       *p++ = v.z();
       *p++ = n.x();
       *p++ = n.y();
       *p++ = n.z();
       m_count += 6;
       Q_ASSERT( m_count <= m_data.size() );
      }
      

      【讨论】:

        【解决方案6】:

        我遇到了类似的错误。这是一个仓促的菜鸟错误。整数数组没有声明大小 int a[] 然后尝试访问它。 如果 C++ 编译器在 main 中,它应该很容易发现这样的错误。然而,由于这个特定的 int 数组是在一个对象内声明的,它与我的对象同时创建(许多对象正在创建)并且编译器抛出一个 free(): invalid next size(normal) 错误。 我想到了两种解释(如果有人知道更多,请赐教): 1.) 这导致为其分配了一些随机内存,但由于无法访问它,它正在释放所有其他堆内存,只是试图找到这个 int。 2.) 程序所需的内存实际上是无限的,分配它是为了释放所有其他内存。

        一个简单的:

            int* a;
            class foo{ 
            foo(){
               for(i=0;i<n;i++)
                   a=new int[i];
             }
        

        解决了这个问题。但是尝试调试它确实花费了很多时间,因为编译器无法“真正”找到错误。

        【讨论】:

        • c++最糟糕的地方就是这个,编译器什么都找不到,只能到处填cout或者使用调试器,这并不总是一个好的解决方案
        猜你喜欢
        • 2012-10-23
        • 2012-10-25
        • 2012-05-22
        • 1970-01-01
        • 2017-03-28
        • 2018-05-20
        • 1970-01-01
        • 2015-04-16
        • 1970-01-01
        相关资源
        最近更新 更多