堆記憶體還是棧記憶體?,堆記憶體還是
《劍指Offer》裡面有一道題目,“把一字元數組中的空格用字串“%20”代替“,看了書上的思路,然後我寫出來的程式當輸入的空格太多時,會出現錯誤“memory clobbered before allocated block”。其原因是沒搞清楚棧記憶體,堆記憶體的分配和區別。錯誤碼如下:
#include <stdio.h>#include <malloc.h>#include <string.h>void replaceSpace(char string[]);int main(){ char string[] = "This is a test!"; //字元數組,在棧記憶體區分配記憶體 replaceSpace(string); printf("%s",string); free(string); return 0;}void replaceSpace(char string[]){ int index, spaceNum; size_t OriginLen, FinalLen; int OriginIndex, FinalIndex; index = 0; spaceNum = 0; OriginLen = 0; while(string[index] != '\0') { if(string[index] == ' ') spaceNum++; OriginLen++; index++; } FinalLen = OriginLen + spaceNum * 2; string = realloc(string,FinalLen); //realloc函數 在堆記憶體區分配記憶體 OriginIndex = OriginLen; FinalIndex = FinalLen; while(OriginIndex >= 0) { if(string[OriginIndex] != ' ') { string[FinalIndex] = string[OriginIndex]; } else { string[FinalIndex] = '0'; string[--FinalIndex] = '2'; string[--FinalIndex] = '%'; } --FinalIndex; --OriginIndex; } }
程式的第9行定義並初始化了一個字元數組string,它的記憶體配置由系統自動在完成,且是在棧上分配的。
當我在replaceSpace函數中要把string中的空格替換成“%20”的時,需要給它擴充記憶體,這是我想到了realloc函數。但不幸的是,realloc函數操作的是堆記憶體,
而我們的string是在棧上分配的,所以realloc函數在堆上根本就找不到string對應的地址,更別說給它擴充記憶體了,所以這個函數返回一個空值,這也就是報錯的原因。
解決方案:
1. 最初就給string字元數組給足空間,不在replaceSpace函數中重新擴充。
char string[100] = "this is a test!";
2. 最初使用malloc函數給string分配空間。
int main(){ char * string; string = (char*)malloc(strlen("test")*sizeof(char)); strncpy(string,"test",strlen("test")); ... }void replaceSpace(char string[]){ string = realloc(string,FinalLen); ... if(string != NULL) { ... } else { printf("alloc memory error!\n"); } ...}
盜一段代碼,(這段代碼對於堆和棧的區別說的很清楚啊):
PS. 關於棧,堆記憶體配置相關文章參考:
http://bbs.csdn.net/topics/390147637
有關堆記憶體與棧記憶體的問題
棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的儲存區。裡面的變數通常是局部變數、函數參數等。
堆,就是那些由new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般一個new就要對應一個delete。如果程式員沒有釋放掉,那麼在程式結束後,作業系統會自動回收。在main()中的int a ;是局部變數
Java中棧記憶體與堆記憶體怎理解?
Object obj = new Object();
以上這句話,會把obj這個引用放進棧記憶體,再說白一點,就是這個對象的名字obj放進棧記憶體,棧記憶體運行速度較快,用於尋找索引(也就是名字)
而new Object()會在堆記憶體中開闢一塊空間給這個對象,對象幾乎所有的屬性啊,方法啊,全都在裡面了,也就是對象的實體都在堆記憶體中 ,堆記憶體速度慢但是成本低,空間較大,用以存放程式