102 Stimmen

Fehler: free(): ungültige nächste Größe (schnell):

Welchen merkwürdigen Fehler erhalte ich? Ich kompiliere C++ unter Verwendung von g++ auf Ubuntu 10.10. Es tritt sporadisch auf, wenn ich die ausführbare Datei starte (vielleicht 2 Mal in 8 Stunden, bei 10 Kompilierungen pro Stunde). Jedoch verschwindet es meistens, wenn ich sauber mache und neu kompiliere.

*** glibc detected *** ./emailQueue.app: free(): invalid next size (fast): 0x0000000001c40270 ***
======= Stacktrace: =========
/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]
======= Speicherkarte: ========
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
... [Remaining content has been translated] ...
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

121voto

James McNellis Punkte 337231

Das bedeutet, dass Sie einen Speicherfehler haben. Möglicherweise versuchen Sie, einen Zeiger freizugeben, der nicht von malloc (oder ein Objekt, das nicht von new erstellt wurde) allokiert wurde, oder Sie versuchen, ein solches Objekt mehr als einmal zu free/delete. Möglicherweise überschreiben Sie einen Puffer oder schreiben anderweitig in den Speicher, in den Sie nicht schreiben sollten, was zu einer Heap-Korruption führt.

Jede Anzahl von Programmierfehlern kann dieses Problem verursachen. Sie müssen einen Debugger verwenden, eine Rückverfolgung erhalten und sehen, was Ihr Programm tut, wenn der Fehler auftritt. Wenn das scheitert und Sie feststellen, dass Sie den Heap zu einem früheren Zeitpunkt beschädigt haben, könnten Sie vor einigen schmerzhaften Debugging-Aufgaben stehen (es könnte nicht allzu schmerzhaft sein, wenn das Projekt klein genug ist, dass Sie es Stück für Stück angehen können).

25voto

vvs14 Punkte 682

Ich habe das gleiche Problem festgestellt, obwohl ich keine dynamische Speicherzuweisung in meinem Programm vorgenommen habe, aber ich habe auf einen Index eines Vektors zugegriffen, ohne Speicher dafür zuzuweisen. Also, wenn es der gleiche Fall ist, ist es besser, etwas Speicher mit resize() zuzuweisen und dann auf die Vektorelemente zuzugreifen.

8voto

orlp Punkte 106335

Wir benötigen den Code, aber das passiert normalerweise, wenn Sie versuchen, den Speicher von einem Zeiger zu free(), der nicht alloziert ist. Dies passiert oft, wenn Sie doppelt freigeben.

7voto

george Punkte 79

Wenn Sie versuchen, Speicherplatz für ein Array von Pointern zuzuweisen, wie zum Beispiel

char** my_array_of_strings;  // oder ein Array von Pointern wie int** oder sogar void**

müssen Sie die Wortgröße (8 Bytes in einem 64-Bit-System, 4 Bytes in einem 32-Bit-System) berücksichtigen, wenn Sie Speicherplatz für n Pointer reservieren. Die Größe eines Pointers entspricht Ihrer Wortgröße.

Also, während Sie vielleicht Speicherplatz für n Pointer reservieren wollen, werden Sie eigentlich n mal 8 oder 4 benötigen (für 64-Bit- oder 32-Bit-Systeme, respektive)

Um ein Überlaufen Ihres reservierten Speichers für n Elemente mit 8 Bytes zu vermeiden:

my_array_of_strings = (char**) malloc( n * 8 );  // für 64-Bit-Systeme
my_array_of_strings = (char**) malloc( n * 4 );  // für 32-Bit-Systeme

Dies gibt Ihnen einen Block von n Pointern zurück, die jeweils aus 8 Bytes (oder 4 Bytes, wenn Sie ein 32-Bit-System verwenden) bestehen

Ich habe festgestellt, dass Linux es Ihnen erlauben wird, alle n Pointer zu verwenden, wenn Sie nicht für die Wortgröße kompensiert haben, aber wenn Sie versuchen, diesen Speicher freizugeben, merkt es seinen Fehler und gibt diesen ziemlich unangenehmen Fehler aus. Und das ist ein schlechter, wenn Sie reservierten Speicher überlaufen, lauern viele Sicherheitsprobleme.

1voto

peter karasev Punkte 2496

Ich bin auf eine Situation gestoßen, in der der Code die API von STL umgeht und unsicher in das Array schreibt, wenn es von jemandem neu dimensioniert wird. Durch das Hinzufügen des asserts habe ich es erwischt:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X