代碼如下:
#include <iostream>
#include <string.h>
using namespace std;
int main() {
char *a = new char[200];
memcpy(a-1, "12345678", 8);
delete[] a;
return 0;
}
執行到delete陳述句時會報“double free or corruption (out):” 的錯誤
a-1那里是用的不對,想知道為啥delete a會有問題,原理是怎樣的?
uj5u.com熱心網友回復:
這里memcpy(a-1, "12345678", 8);為什么是 a-1 ????
uj5u.com熱心網友回復:
這個我知道有問題,只是故意弄了個錯誤,我是想知道這種情況下為啥delete a會報錯。
uj5u.com熱心網友回復:
你操作了沒有分配給你的記憶體uj5u.com熱心網友回復:
錯誤是因為上一行代碼挖的坑
uj5u.com熱心網友回復:
那怎么不是memcpy那里報錯呢
uj5u.com熱心網友回復:
我知道是那里的問題, 就是不太懂為啥我在delete a的時候會報這個錯,a的指標也沒動,還是指向的之前new的記憶體。
uj5u.com熱心網友回復:
new -> deletenew [] ->delete[]
。
delete 做了一些事情的。或者說。
delete和delete[]做的事情還是有可能不大一樣的。
不報錯,運行正常乃是運氣八錯。
報錯了該認還是得認
uj5u.com熱心網友回復:
至于你這個的正常delete方法,我且思索一會兒
uj5u.com熱心網友回復:
啊,搞錯了,前面當我在放屁。
uj5u.com熱心網友回復:
你操作了沒有分配給你的記憶體
那怎么不是memcpy那里報錯呢
寫入未分配的地址,這屬于未定義行為,具體如何操作,這是微軟自己定義的,你可以這么理解,寫入沒有檢測,而洗掉時檢測了,于是就報了例外,寫代碼最好不要使用未定義,除非你能準確地了解他。
uj5u.com熱心網友回復:
錯誤是因為上一行代碼挖的坑
我知道是那里的問題, 就是不太懂為啥我在delete a的時候會報這個錯,a的指標也沒動,還是指向的之前new的記憶體。
uj5u.com熱心網友回復:
堆疊溢位錯誤。
錯誤是因為上一行代碼挖的坑
我知道是那里的問題, 就是不太懂為啥我在delete a的時候會報這個錯,a的指標也沒動,還是指向的之前new的記憶體。
請問一下delete失敗的原理是啥?我理解的是我沒有動過a的指標
uj5u.com熱心網友回復:
因為new之后,實際分配出來的記憶體是要比你要求分配的記憶體大的。對于delete,它怎么能知道到底要delete掉多少記憶體?
那是因為new的時候,他會把最開始的那一段記憶體留下,用來存盤關于被分配給你使用的那段記憶體的資訊
然后回傳給你的是該首段記憶體之后的記憶體地址。
你那句有a-1的記憶體復制函式就導致了這段存盤記憶體資訊的記憶體被其他資訊覆寫,導致之后無法進行delete或者delete出錯。
因為存盤記憶體資訊的地址內容被你覆寫沒了,所以delete也就報錯了
uj5u.com熱心網友回復:
使用p = malloc分配記憶體時,記憶體管理器需要記錄這塊記憶體的資訊。大部分記憶體管理器把這些資訊保存在p前面的幾個位元組里。memcpy破壞了這些資訊,導致后續free失敗。uj5u.com熱心網友回復:
delete 不了,可以試試free
uj5u.com熱心網友回復:
堆疊溢位問題吧uj5u.com熱心網友回復:
a-1。。。不是你的記憶體你也用,還釋放。。崩潰算好的了uj5u.com熱心網友回復:
為了驗證錯誤,樓主也是夠拼的了uj5u.com熱心網友回復:
new []會在首地址前4個位元組定義陣列長度。當delete[]時,會根據前4個位元組所定義的長度來執行解構式洗掉整個陣列。
如果只是delete陣列首地址,只會洗掉第一個物件的值。
uj5u.com熱心網友回復:
new []會在首地址前4個位元組定義陣列長度。
當delete[]時,會根據前4個位元組所定義的長度來執行解構式洗掉整個陣列。
如果只是delete陣列首地址,只會洗掉第一個物件的值。
不對。。。。
只有自定義型別,且提供了解構式的型別,才會在前面放置長度。
uj5u.com熱心網友回復:
請問一下delete失敗的原理是啥?我理解的是我沒有動過a的指標
簡單給你解釋一下吧。。
你想過一個問題沒,new啊、malloc之類的,new多少位元組在哪里存放,釋放記憶體之后,系統怎么判斷這部分記憶體釋放掉了,然后可以回收再利用……其實一般來說c/c++系統層面維護了一個雙向鏈表,記錄了下一次new/malloc的位置之類的資訊,一般就在你這個a之前的20位元組左右(不同作業系統,不同位編譯器結果不同),你a-1的越界行為,破壞了人家系統的鏈表結構,所以出錯了……
你試著
int *a = new int[80];
int *b = new int[80];
//觀察a、b地址查多少
//也可以試著看看a之前20-30個位元組分別是啥,大概就知道系統記錄的資訊
//當然有系統庫提供的函式可以直接看這個鏈表,具體忘了
uj5u.com熱心網友回復:
找到匯編語言萬事大吉那樣就可以自己分析了
哎
uj5u.com熱心網友回復:
VS2015里面的報錯資訊CRT detected that the application wrote to memory before start of heap buffer.
其實在delete時,才檢測到在堆緩沖區起始位置之前的記憶體中進行了寫入處理
uj5u.com熱心網友回復:
memcopy不檢測的啊,經常出現的資料亂了,崩潰啥的就是這個干的uj5u.com熱心網友回復:
// 0xFDFDFDFD Used by Microsoft's C++ debugging heap// to mark "no man's land" guard bytes
// before and after allocated heap memory
uj5u.com熱心網友回復:
memcpy(a-1, "12345678", 8)這里錯了uj5u.com熱心網友回復:
// MFC 下 malloc
int Test()
{
#define BackNum 4
int *p1,*p2,*p3,*p4,*p5,*p6;
p1=(int*)malloc(16);
afxDump << *(p1-BackNum) <<"\n";// 16
p2=(int*)malloc(32);
afxDump << *(p2-BackNum) <<"\n";// 32
p3=(int*)malloc(100);
afxDump << *(p3-BackNum) <<"\n";// 100
p4=(int*)malloc(200);
afxDump << *(p4-BackNum) <<"\n";// 200
p5=(int*)malloc(300);
afxDump << *(p5-BackNum) <<"\n";// 300
p6=(int*)malloc(400);
afxDump << *(p6-BackNum) <<"\n";// 400
// p-1== 0xFDFDFDFD
// _CrtMemBlockHeader
// 0xFDFDFDFD Used by Microsoft's C++ debugging heap
// to mark "no man's land" guard bytes
// before and after allocated heap memory
free(p1);
free(p2);
free(p3);
free(p4);
free(p5);
free(p6);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/42713.html
標籤:C++ 語言
上一篇:一個關于英漢電子詞典的,麻煩大佬們幫我看下、解決下問題,我怎么搞都不行,謝謝了
下一篇:求編程程序
