Reputation: 582
I'm programming C on a microchip that doesn't support any memory allocation commands, but it does like pointers (of course). So my question is:
Is there a way to define an array within a function, and pass the pointer to that array back to a global variable?
This would be a way to have a dynamic memory use WITHOUT malloc, realloc, or calloc. Essentially stack memory being passed back to global WITHOUT it destroying itself. I'm assuming that the alloc commands are specifically needed to ensure it doesn't get destroyed, but I wanted to check and see if there was a way around this.
Upvotes: 1
Views: 1275
Reputation: 663
The main problem is function calls and how calls affect stack. On IBM architecture, simply, current EBP pushed to stack, caller stack frame is saved to EBP and callee parameters pushed to stack(generally). On return pushed EBP is poped and stack allocated parameters could be overwritten by caller, that area is free to use since callee is returned.
When you some how dynamically allocate some space on stack, it's a possibility to overwrite that space somewhere in time at a function call which has some wide veriaty of parameters or recursive calls. This is why all dynamic allocations happens in Heap and heap management is at the hands of operating system. Since malloc (etc) is o.s. wrappers for heap allocations you do not need to worry about that management, o.s. will take it care for you.
If you want to achieve dynamic allocations on stack you need to go with assembly. Make sure allocate enough space before a function call at the caller site and take that space back when caller will be returned to its caller. And that organisation would be a brainfk i guess..
Upvotes: 1
Reputation: 153517
A simple way to allocate memory on the "stack", pass its address to a global memory.
A potential reason to do so would be to create a "State" (Set of data), but to not have to pass it to sub-functions as the nesting could be very deep and stack savings may be had. The price in that multi-threaded applications could not use Function()
safely.
Notice that anything that calls Function()
should not use 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();
}
Upvotes: 0
Reputation: 215277
It's possible to store the address of an object with automatic storage duration (your array "on the stack") in a global variable, but this does not in any way increase the lifetime of the object. It still ceases to exist when execution of the block in which it's declared ends. And after it ceases to exist, any further use of the pointer you stored in your global variable would result in undefined behavior.
Upvotes: 1
Reputation: 5612
Do you mean something like this?
char* x;
int main(int argc, char** argv) {
static char foo[80];
x = foo;
// ...
}
This puts your buffer in the BSS segment. If you want it to remain on the runtime stack, get rid of the static
.
foo
has automatic storage (basically, it's size is fixed), but you now have a globally visible pointer to it.
It will hold until main
returns, which presumably, is the end of your process and you don't need it anymore.
If you want to have truly dynamic memory, you'll have to write your own memory allocator, as suggested in the comments.
Upvotes: 1
Reputation: 171
You would need to define a huge global array to reserve a big chunk of memory then use that array instead. If you prefer you can also write some simple alloc/free function to allocate/free blocks from that array.
Stack memory will be reused by the next function call. So it is not possible for you to keep anything after the function returns. Of course, if you know your function won't return while that variable is used (for example, a local variable of the main function), then it's safe to pass the pointer to that variable around.
Upvotes: 2
Reputation: 2988
malloc
is often accompanied by a small stack.alloca
function the result it the same.But, the memory is only safe until you return from the function the array is in, so you can't turn this into a malloc
style thing, but rather only generate memory/scratch for your call children.
Upvotes: 2
Reputation: 981
You could define the array as static in the function and assign the value to a global pointer. Not sure I would call this a good programming practice.
Note that this only gets you 1 copy of the array so subsequent calls to your function won't create additional instances of your array. In which case I would ask why don't you just make the array global in the first place?
Upvotes: 1