Calculating stack memory size in C from pointers, on Linux Debian?

96 Views Asked by At

Inspired by this related SO answer, I am trying to obtain stack memory usage (as distinct from heap memory) on Linux Debian 9, without much success. I have created some testing code that doesn't produce expected results:

size_t top_of_stack = 0;

int main(void) {
    int x = 0;
    top_of_stack = (size_t) &x;
    printf("Top of stack in main(): %lu\n", top_of_stack);
    int y = 0;
    size_t ss1 = (size_t) &y;
    printf("Top of stack in main() ss1: %lu\n", ss1);
    printf("Diff in main() top - ss1: %lu\n", top_of_stack - ss1);
    long z = 0;
    size_t ss2 = (size_t) &z;
    printf("Top of stack in main() ss2: %lu\n", ss2);
    printf("Diff in main() ss1 - ss2: %lu\n", ss1 - ss2);
    double dd1[100];
    dd1[99] = 12.0;
    dd1[98] = 121.0;
    dd1[97] = 122.0;
    size_t ss3 = (size_t) &(dd1[99]);
    printf("Top of stack in main() ss3: %lu\n", ss3);
    printf("Diff in main() ss2 - ss3: %lu\n", ss2 - ss3);
    return 0;
}

The printout:

Top of stack in main(): 140733255163788
Top of stack in main() ss1: 140733255163784
Diff in main() top - ss1: 4
Top of stack in main() ss2: 140733255163776
Diff in main() ss1 - ss2: 8
Top of stack in main() ss3: 140733255163768
Diff in main() ss2 - ss3: 8

Of the three "Diff" printouts, only the first seems correct. The second does not account for the fact that two long variables have been created (long z and size_t ss1), not one. The third "Diff" report doesn't account for the fact that an array of 100 doubles has been created, with the last three items assigned values.

How can this be made to work?

Note that although I am able to include the "alloc.h" header on my system, the stackavail() function is not available. This is the reason I am trying to develop my own solution.

1

There are 1 best solutions below

5
On BEST ANSWER

C does not make any guarantees about stack layout. As far as the compiler is concerned, it can add or remove variables any way it likes as long as it does not affect the observable behavior. It can also introduce padding in any way it want.

I don't know of any way to do this in an exact manner. But if you just need a quick estimate that does not need to be computed during runtime, just sum up all the local variables. It will not be exact, and probably a little bit below the real value because of padding and other stuff.

But comparing pointers is a bad idea. If you have two pointers, void *p, *q; then the operation p-q is meaningless, unless p and q points to the same object. The operation is actually likely to invoke undefined behavior. This answer explains it.