これまでに割り当てられていなかったメモリを解放しようとしたため、この時点で取得するsegfaultは、オペレーティングシステムが許可していないメモリアドレスを参照しようとするためsegfaultが発生します(セグメンテーション違反の定義です)。
いくつかの実験では、あなたが出力としてこれを得るでしょう、あなたはvalgrindの中であなたのサンプルコードを実行しますと言う:
==6945== Invalid free()/delete/delete[]
==6945== at 0x402265C: free (vg_replace_malloc.c:323)
==6945== by 0x80483D5: main (bla.c:6)
==6945== Address 0x7 is not stack'd, malloc'd or (recently) free'd
==6945==
==6945== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1)
==6945== malloc/free: in use at exit: 4 bytes in 1 blocks.
==6945== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.
は、これは「PURが歌った」メモリリークです。今度は、解放しようとするポインタが割り当てたポインタの近くにあるようにコードを変更するとします(オペレーティングシステムはまだアクセスしていますが、オペレーティングシステムはバイト境界でメモリアクセスを許可しません)。私たちは、このようなコードを変更すると言う:
int main(){
int* c;
c = (int*)malloc(sizeof(int));
c++;
free(c);
return 0;
}
このアプリケーションを実行している場合、あなたが長い(カーネルによって放出された)セグメンテーションフォールトが、glibcのからの警告を取得しません(malloc関数の所有者を()とfree())
[email protected]:/tmp$ ./a.out
*** glibc detected *** ./a.out: free(): invalid pointer: 0x0804a00c ***
... followed by a trace
だから、カーネルが、それはあなたに属している知っているのが、あなたにそれを配って覚えていないことができたglibcの一部のメモリを解放しようとしています。
==6955== Invalid free()/delete/delete[]
==6955== at 0x402265C: free (vg_replace_malloc.c:323)
==6955== by 0x80483D2: main (bla.c:5)
==6955== Address 0x418a02c is 0 bytes after a block of size 4 alloc'd
==6955== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==6955== by 0x80483C0: main (bla.c:3)
==6955==
==6955== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1)
==6955== malloc/free: in use at exit: 4 bytes in 1 blocks.
==6955== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.
:あなたはこの出力を得るでしょう(libcの中で、()はmalloc()、reallocの()、...の機能を自由に交換し、独自に会計処理を実行することにより動作する)valgrindの中でこれを実行したい場合伝統的なUnixガベージコレクションスキーム:プログラムを実行し、終了時にメモリを再利用します。長い時間稼働している可能性が高いIDEやブラウザ、その他のプログラムではうまく機能しません。 –