是否有可能在當前函數退出之前顯式釋放由C的alloca()分配的內存?如果是這樣,怎麼樣?釋放alloca分配的內存
回答
這是可能的,但沒有預先寫好的功能。你必須深入研究你的編譯器的alloca()實現,找出它在做什麼,然後編寫你自己的freea()。由於每個編譯器都以不同的方式執行alloca(),所以必須爲每個編譯器重寫freea()。
但我覺得很難相信這是值得的麻煩。如果需要明確釋放它,只需使用malloc/free,這些函數通常會進行大量優化。利用它們。
一個可移植的實現是「void freea(void * p){} //只是僞造它」。 – paxdiablo 2008-11-12 06:49:06
不,因爲它與本地變量一起被分配在堆棧上。如果你想要顯式地釋放內存,可以使用其中一種動態內存分配函數。
有沒有混合允許你明確地自由和讓它在函數退出時自動釋放,至少不在標準中。
您正在使用alloca()分配堆棧。如果事後發生了其他事情(如果沒有在彙編中編寫所有東西,你無法控制它),你不能只收縮堆棧。所以直到你離開函數的堆棧框架,這是不可能的。
這也是爲什麼你可以真正搞砸了,如果你溢出分配的緩衝區。你可以開始覆蓋函數返回的代碼地址,使它跳轉到其他地方,各種可怕的東西。小心!
Malloc在堆上工作,所以這就是爲什麼它可以做的更靈活。
從http://www.gnu.org/software/libc/manual/html_mono/libc.html#Variable-Size-Automatic:
分配與
alloca
一個塊是一個明確的動作;您可以根據需要分配儘可能多的塊,並在運行時計算大小。但是當你退出alloca被調用的函數時,所有的塊都被釋放,就像它們是在該函數中聲明的自動變量一樣。 沒有辦法明確釋放空間。
這對連續傳球風格(CPS),而不是realloca很有用。
在將棧縮回到字符串的長度並調用下一個函數之前,可以調用一個函數來分配和操作棧頂的一個字符串。
沒有概念上的原因,爲什麼不能有一個freea(),除了堆棧中最頂層的入口外,其他任何東西都是nop。
使用C99,您可以使用Variable Length Array實現同樣的功能。只需在新的範圍內宣佈VLA;它會在範圍退出時自動釋放。
例如:
int some_function(int n) {
// n has the desired length of the array
...
{ // new scope
int arr[n]; // instead of int *arr = alloca(n*sizeof(int));
// do stuff with array
}
// function continues with arr deallocated
...
}
是的,但是這取決於ALLOCA的實現()。 alloca()的一個合理而簡單的實現是通過調整堆棧指針,將新分配的塊放置在棧頂的上。因此,要釋放此內存,我們只需要做一個負分配(但你需要學習真正落實了alloca()的),讓我們通過以下非便攜代碼,例如驗證:
#include <stdio.h>
#include <alloca.h>
int main()
{
unsigned long p0, p1, p2;
p0=(unsigned long)alloca(0);
p1=(unsigned long)alloca((size_t) 0x1000);
p2=(unsigned long)alloca((size_t)-0x1000);
printf("p0=%lX, p1=%lX, p2=%lX\n", p0, p1, p2);
return 0;
}
在一箇舊的x64機器鏗鏘2.9,樣品輸出爲:
p0=7FFF2C75B89F, p1=7FFF2C75A89F, p2=7FFF2C75B89F
所以我們知道實現不驗證參數-0x1 000,否則無符號值將是一個非常大的整數。堆棧指針最初是0x ... B89F;因爲這個堆棧向上增長alloca(0x1000)因此將堆棧指針向上改爲爲(0x ... B89F - 0x1000)= 0x ... A89F。負分配後(0xA89F - ( - 0x1000))堆棧指針返回0x ... B89F。
然而,用gcc 4.8.3,樣品輸出爲:
p0=7FFFA3E27A90, p1=7FFFA3E26A80, p2=7FFFA3E27A70
在/usr/include/alloca.h裏面我們發現:
#ifdef __GNUC__
# define alloca(size) __builtin_alloca (size)
#endif /* GCC. */
所以我們知道,內建ALLOCA由gcc 4.8.3提供的函數做了類似的事情,除了它分配額外的0x10字節作爲安全邊界。在進行負分配時,它仍然假設它向上增長,因此試圖保留0x10個額外字節( - 0x10),所以p2 = 0x ... 6A80 - ( - 0x1000) - 0x10 = 0x ... 7A70。所以,要特別小心。
- 1. 釋放分配的內存
- 2. 分配和釋放內存
- 3. 內存分配和釋放
- 4. 分配alloca的內存在函數結束或範圍結束時被釋放?
- 5. Ç - 內存分配和釋放內存
- 6. 分配/釋放內存內循環
- 7. 釋放由cudamallocpitch分配的內存
- 8. 釋放動態分配的內存
- 9. 誰負責釋放分配的內存?
- 10. 如何釋放Swingworker分配的內存?
- 11. C內存分配和釋放
- 12. 在C++中分配和釋放內存
- 13. C++堆內存分配/釋放
- 14. 釋放內存分配給Java中
- 15. 關於釋放內存分配C
- 16. 自動釋放內存分配
- 17. 何時使用alloca爲類成員釋放內存?
- 18. 釋放分配給指針的內存vs釋放分配給指針指向的內存
- 19. 內存泄漏,儘管釋放分配的內存
- 20. cv :: Mat內存分配和釋放內存
- 21. MFC/OLE拖放 - 釋放全局分配的內存
- 22. 釋放分配的內存會生成分段錯誤
- 23. 如何釋放或釋放我分配給.wav文件的內存?
- 24. Java內存分析顯示異常對象分配和釋放
- 25. 簡單的問題釋放分配的內存
- 26. 在C中的宏中有條件釋放分配的內存
- 27. 釋放由賦值運算符分配的內存C++
- 28. 在Solaris/Linux中釋放分配的內存
- 29. 內存分配,釋放和NSURLConnection的在iPhone應用程序
- 30. 內存分配/釋放錯誤(非常小的代碼)
你能解釋一下你的動機嗎?爲什麼你想在返回之前釋放分配的空間? – Motti 2008-12-07 20:22:08