エラー:free():次のサイズが無効です(高速):


90

この奇妙なエラーは何ですか?Ubuntu 10.10でg ++を使用してC ++をコンパイルしています。実行可能ファイルを実行すると、ランダムにポップアップ表示されます(多分8時間に2回、1時間に10回コンパイルされます)。ただし、クリーンにして再コンパイルすると、ほとんどの場合それはなくなります。

*** 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

1
セミコロンがないためにこのエラーが発生しました。
atzol

回答:


105

これは、メモリエラーがあることを意味します。あなたはしようとすることができるfreeによって割り当てられていないポインタmalloc(またはdeleteによって作成されていないオブジェクトnew)または、あなたがしようとすることができるfree/ delete回以上このようなオブジェクト。バッファをオーバーフローさせるか、書き込みを禁止するメモリに書き込みを行っているため、ヒープが破損している可能性があります。

プログラミングエラーがいくつもあると、この問題が発生する可能性があります。デバッガーを使用してバックトレースを取得し、エラーが発生したときにプログラムが何を実行しているかを確認する必要があります。これが失敗し、以前のある時点でヒープが破損していると判断した場合、苦痛なデバッグが発生している可能性があります(プロジェクトが少しずつ対応できるほど小さい場合は、それほど苦痛ではないかもしれません)。


37
valgrindなどのツールは、これらのタイプのエラーの原因を見つけるときに非常に役立ちます。必ずデバッグシンボルを使用してコンパイルしてください。
Daniel Gallagher

3
参考:std :: vector <>のサイズを変更した後、これが十分に大きくなかったため、これが発生しました。
Adam27X 2014

1
本当に?ベクトルが十分に大きくない場合、free()で問題が発生しました。少なくとも最初に質問を読んでください。
gyan

21

プログラムで動的メモリ割り当てを行わなかったにもかかわらず、同じ問題が発生しましたが、メモリを割り当てずにベクトルのインデックスにアクセスしていました。そのため、同じ場合は、resize()ベクター要素を使用してメモリを割り当ててからアクセスしてください。


7

コードが必要ですが、free()割り当てられていないポインターからメモリを使おうとすると、通常ポップアップします。これは、二重解放の場合によく発生します。


6

次のようなポインタの配列にスペースを割り当てようとしている場合

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

次に、n個のポインターにスペースを割り当てるときは、ワードサイズ(64ビットシステムでは8バイト、32ビットシステムでは4バイト)を考慮する必要があります。ポインターのサイズは、ワードサイズと同じです。

したがって、n個のポインターにスペースを割り振ることもできますが、実際には8倍または4倍のnが必要になります(それぞれ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

これは、それぞれが8バイト(32ビットシステムを使用している場合は4バイト)で構成されるn個のポインターのブロックを返します。

Linuxでは、ワードサイズを補正していなければ、すべてのnポインタを使用できることに気づきましたが、そのメモリを解放しようとすると、エラーが発生し、かなり厄介なエラーが発生します。そしてそれは悪いことです。割り当てられたメモリをオーバーフローすると、多くのセキュリティ問題が待ち受けます。


2
を使用して4バイトまたは8バイトをハードコードする代わりに、同じコードを任意のシステムに汎用にすることができますsizeof(char*)
ベンG.

sizeofmalloc を使用するときに演算子を使用しないことは、本当に問題を引き起こすだけです。IIRC標準ではcharのサイズが保証されていますが、それ以外はほとんどISAに任されているため、sizeofどこでも使用するのが最善です。
ajxs

1

私は、コードが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() );
}

1

同様のエラーが発生しました。それは急いで行われた初心者の間違いでした。サイズint a []を宣言せずにアクセスしようとする整数配列。C ++コンパイラーは、メインにあれば、このようなエラーを簡単にキャッチするはずです。ただし、この特定のint配列はオブジェクト内で宣言されているため、オブジェクトと同時に作成され(多くのオブジェクトが作成されていました)、コンパイラーがfree():invalid next size(normal)エラーをスローしていました。私はこれについて2つの説明を考えました(誰かがもっと知っていれば教えてください):1.)これによりランダムなメモリが割り当てられましたが、これにアクセスできなかったため、他のすべてのヒープメモリを解放しようとしていましたこのint。2.)プログラムが必要とするメモリは、プログラムにとって事実上無限であり、これを割り当てるために、他のすべてのメモリを解放していました。

シンプルな:

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

問題を解決しました。しかし、コンパイラがエラーを「本当に」見つけることができなかったため、これをデバッグしようとするとかなりの時間がかかりました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.