我在不支持任何内存分配命令的微芯片上编程C,但它确实喜欢指针(当然)。所以我的问题是:
有没有办法在函数中定义数组,并将指向该数组的指针传递回全局变量?
这将是一种在没有malloc,realloc或calloc的情况下使用动态内存的方法。基本上堆栈内存被传递回全局而不会破坏它自己。我假设特别需要alloc命令来确保它不被破坏,但我想检查一下是否有解决方法。
答案 0 :(得分:2)
malloc
通常伴随着一个小堆栈。alloca
函数,结果都是相同的。但是,在从数组所在的函数返回之前,内存才是安全的,因此您无法将其转换为malloc
样式,而只是为您的调用子项生成内存/暂存。
答案 1 :(得分:2)
您需要定义一个巨大的全局数组来保留大块内存然后使用该数组。如果您愿意,还可以编写一些简单的alloc / free函数来分配/释放该数组中的块。
下一个函数调用将重用堆栈内存。因此,在函数返回后,您无法保留任何内容。当然,如果你知道在使用该变量时你的函数不会返回(例如,main函数的局部变量),那么将指针传递给该变量是安全的。
答案 2 :(得分:1)
你的意思是这样吗?
char* x;
int main(int argc, char** argv) {
static char foo[80];
x = foo;
// ...
}
这会将您的缓冲区放入BSS段。如果您希望它保留在运行时堆栈上,请删除static
。
foo
有自动存储(基本上,它的大小是固定的),但你现在有一个全局可见的指针。
它将一直持续到main
返回,这可能是你的过程的结束,你不再需要了它。
如果你想拥有真正的动态内存,你必须按照评论中的建议编写自己的内存分配器。
答案 3 :(得分:1)
您可以在函数中将数组定义为静态,并将值赋给全局指针。不确定我会称这是一个很好的编程习惯。
请注意,这只会获得一个数组副本,因此对函数的后续调用不会创建数组的其他实例。在这种情况下,我会问你为什么不首先将数组设为全局?
答案 4 :(得分:1)
可以在全局变量中存储具有自动存储持续时间(您的数组“在堆栈中”)的对象的地址,但这不会以任何方式增加对象的生命周期。当执行声明结束的块时,它仍然不存在。在它不再存在之后,进一步使用存储在全局变量中的指针将导致未定义的行为。
答案 5 :(得分:1)
主要问题是函数调用以及调用如何影响堆栈。在IBM体系结构上,简单地说,当前EBP被推送到堆栈,调用者堆栈帧被保存到EBP并且被调用者参数被推送到堆栈(通常)。在返回时,推送的EBP被激活,并且调用者可以覆盖堆栈分配的参数,因为返回被调用者,该区域可以自由使用。
当你在堆栈上动态分配一些空间时,它有可能在函数调用的某个时间覆盖该空间,该函数调用具有一些广泛的参数或递归调用。这就是为什么所有动态分配都在堆中发生,并且堆管理由操作系统完成。因为malloc(等)是o.s.用于堆分配的包装器,您无需担心该管理,o。会照顾你。
如果要在堆栈上实现动态分配,则需要使用汇编。确保在调用者站点的函数调用之前分配足够的空间,并在调用者返回其调用者时占用该空间。而且我猜这个组织会是一个脑力劳动......
答案 6 :(得分:0)
在“堆栈”上分配内存的简单方法,将其地址传递给全局内存。
这样做的一个潜在原因是创建一个“状态”(数据集),但不必将其传递给子函数,因为嵌套可能非常深,可能会有堆栈节省。多线程应用程序中的价格无法安全使用Function()
。
请注意,调用Function()
的任何内容都不应使用State
。
static char *State;
static int FunctionFoo_Helper(void) {
if (*State != '\0') {
// Do _something_ more interesting than simply print
printf("%c", *State++);
FunctionFoo_Helper();
}
}
void Function(size_t n) {
char Array[n]; // Variable size array
// As to if the system put this on the stack or elsewhere is system dependent.
Populate Array(Array);
Array[n-1] = '\0';
State = Array;
FunctionFoo_Helper();
}