Mark Löwe
Mark Löwe

Reputation: 582

Can you define an array on the stack and pass the pointer to a global variable?

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

Answers (7)

Hasan Manzak
Hasan Manzak

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

chux
chux

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

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

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

sandymatt
sandymatt

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

user3015039
user3015039

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

RichardPlunkett
RichardPlunkett

Reputation: 2988

  1. Yes you can declare arrays in functions. The memory for the array will be on the call stack - though be careful, no malloc is often accompanied by a small stack.
  2. Yes, you can give the address of a locally declared array to a globally declared pointer.
  3. Yes it can be a handy source of dynamic memory in some circumstances, but whether you are declaring a local array or calling the much maligned 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

CodeWhore
CodeWhore

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

Related Questions