7

So from my previous memmove question I would like to know how to find direction of stack growth.

  void stackDirection(int* i)
  {

     int j;

     if(&j>i)
         cout<<"Stack is growing up \n"<<endl;
     else 
         cout<<"Stack is growing down \n"<<endl;


   }
  int main()
  {    
      int i=1;

      stackDirtection(&i);

 }
brett
  • 5,379
  • 12
  • 43
  • 48
  • 2
    And your code doesn't work, or where's the problem? – nothrow Aug 26 '10 at 06:43
  • The problem is I cant say whether this code is correct – brett Aug 26 '10 at 06:54
  • imo a better test would be sequential _alloca calls, as the stack pointers would be in the same stack frame, and wouldn't be subject to any compiler optimizations – Necrolis Aug 26 '10 at 07:23
  • If you perform an experiment, and get valid and reproducible results… – Potatoswatter Aug 26 '10 at 07:24
  • It is better to compare the address of two variables in the same funtion itself. In main itself, you can create j variable and compare the address. It should give the valid result. – bjskishore123 Aug 26 '10 at 08:29
  • @bjskishore123: Two variables in the same function won't give the answer. You'll only be testing how variables are laid out within one stack frame, not how the stack grows. – Mike Seymour Aug 26 '10 at 09:11

5 Answers5

14

The stack may not grow up or down.

Each stack frame can potentially be allocated at random points inside the heap.
This is actually done in several OS to try and prevent stack smashing by malicious code.

The concept of a stack growing towards the heap is just an easy way to teach the concept of a stack (and of course early implementations did work this way as it was simple (no need to make something harder than you need when nobody is trying to break you)).

Martin York
  • 257,169
  • 86
  • 333
  • 562
  • @Martin Stack is created on the heap ? I dint get it ? OS seperates stack from heap right and divides them into pages right ? How can this be architecture dependent ? Because what I am referring here is logical addresses right and these logical addresses are just compiler dependent right? – brett Aug 26 '10 at 08:05
  • @Brett: from the perspective of the hardware, all memory is just memory. The OS can then choose to do whatever it wants. – Potatoswatter Aug 26 '10 at 08:15
  • 1
    @brett: In the old days stack and heap were separate entities and conceptually grew towards each other. But this was rather easy to corrupt and cause malicious code execution. So some clever people had a little think. Now a stack is just a series of frames (one for each function call). There is no technical reason they need to go one after the other (as the current one has a link back to the last). So why not just allocate stack frames in the heap using normal memory management routines. Conceptually: Unwinding the stack is freeing the current frame and following the chain back. – Martin York Aug 26 '10 at 15:52
  • @brett: It's probably slightly more complex than that but conceptually there is no reason each stack frame can not be allocated within the heap. The implementation details of the stack should make no difference to the executing code as long as function local variables are correctly destroyed on exit from the local scope. Its a classic OO design (The run time changed the implementation of a stack frame but the code did not need to know as the interface to the stack frame was identical. The only effected code was relying on the implementation details of the stack (like your code)). – Martin York Aug 26 '10 at 15:55
  • @Martin York Can you point me to some article or a book explaining me this please – brett Aug 26 '10 at 17:59
  • @brett: There is no standard way. What I am saying is you can not assume up or down or even distribution. How the stack is actually implemented is an implementation details that is left up to the compiler. Your best bet is to read your compilers specific documentation on how the stack is implemented. – Martin York Aug 26 '10 at 18:07
1

Experiments such as this are unreliable, because you can run into exceptions. The optimiser can mess you up, or the system might use registers for parameters. If you really must know the stack direction, read the manual for your processor.

Notwithstanding that, unless you are writing an operating system or something really low-level, if you need to know the stack direction you are probably doing something ugly and horrible and should really reconsider your methods.

Michael J
  • 7,631
  • 2
  • 24
  • 30
0

Your function depends on int* parameter which can point to anywhere, and also be NULL. It is better to compare addresses of two local variables.

Alex F
  • 42,307
  • 41
  • 144
  • 212
  • The compiler is free to allocate local variables in any order. Yes, it will construct and destroy them in the right order, but it can allocate space for them wherever it wants. – sharptooth Aug 26 '10 at 06:49
0

This is outside the scope of the C++ standard. It an implementation defined behavior and probably depends on the specific OS/processor architecture etc.

It is best not to rely or depend on such details, unless you are into ETHICAL hacking :) and / or not so much concerned with portability

Chubsdad
  • 24,777
  • 4
  • 73
  • 129
0

Consider the following rewrite, which exposes one way in which a compiler may implement your code:

void stackDirection(int* i) { struct __vars_stackDirection { int j; } *__stackframe_stackDirection = malloc(sizeof(int));

 if(&(__stackframe.j) > i)
     cout<<"Stack is growing up \n"<<endl;
 else 
     cout<<"Stack is growing down \n"<<endl;

} int main() {
struct __vars_main { int i; } *__stackframe_main = malloc(sizeof(int));

  stackDirection(&(__stackframe.i));

}

You'll have to agree that __stackframe_stackDirection and __stackframe_main will be essentially random. The stack can grow up or down.

Worse, you are assuming a lineair model. Either a<b, b<a, or a==b. But for pointers this does not hold. All three comparisons a<b, b<a and a==b may be false at the same time.

MSalters
  • 173,980
  • 10
  • 155
  • 350