是否有可能在当前函数退出之前显式释放由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. 分配alloca的内存在函数结束或范围结束时被释放?
- 3. 内存分配和释放
- 4. 分配和释放内存
- 5. 内存分配释放
- 6. Ç - 内存分配和释放内存
- 7. 内存分配和释放内存
- 8. 分配/释放内存内循环
- 9. 分配/释放内存(Windows下的C++)
- 10. 分配最近释放的内存
- 11. 静态分配的内存释放
- 12. 释放分配有newCString的内存
- 13. 如何释放Swingworker分配的内存?
- 14. 谁负责释放分配的内存?
- 15. 释放动态分配的内存
- 16. 释放由cudamallocpitch分配的内存
- 17. 强制Windows释放分配的内存
- 18. C - 释放内存分配功能
- 19. 关于释放内存分配C
- 20. C内存分配和释放
- 21. 在openCV中释放内存分配
- 22. 释放内存分配给Java中
- 23. 自动释放内存分配
- 24. 在C++中分配和释放内存
- 25. C++堆内存分配/释放
- 26. 何时使用alloca为类成员释放内存?
- 27. 释放分配给指针的内存vs释放分配给指针指向的内存
- 28. 内存泄漏,尽管释放分配的内存
- 29. 二维数组的连续内存分配---释放内存
- 30. 如何分配内存以及如何释放内存?
你能解释一下你的动机吗?为什么你想在返回之前释放分配的空间? – Motti 2008-12-07 20:22:08