[SOLVED] Explorations in memory allocation in ANSI C
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
$ gcc -o alloc alloc.c
alloc.c:34: error: size of array ‘pool3’ is too large
now... can anyone tell me, why does gcc does this? I mean, are there minimum / maximum sizes for an array to be statically allocated? Could anyone point me towards some documentation?
Another scenario I tried is to allocate a 1D array defined as:
Code:
/* 100,000,000 MILLIONS OF MILLIONS: */
#define WARNING 100000000000000000000
char pool2[WARNING];
I tried then to do this:
Code:
int main(void) {
pool2[0] = 'a';
pool2[WARNING - 1] = 'z';
printf("Apparently, if I print this, the allocation was successful...\n");
printf("Some values: %c and %c.\n", pool2[0], pool2[WARNING - 1]);
...
}
I get the following complains in compilation time:
Code:
$ gcc -o alloc alloc.c
alloc.c:32:12: warning: integer constant is too large for its type
alloc.c:58:9: warning: integer constant is too large for its type
alloc.c:60:55: warning: integer constant is too large for its type
And I get this, when I execute it:
Code:
$ ./alloc
Killed
$
Any explanations / useful links?
I mean, I can always read the man entry for gcc but I rather ask because I can then have interaction... I mean, isn't that the whole purpose of forums?
But what happens if it is larger? Some sort of overflow in compilation time perhaps?
Thanks for reply!
And btw, if you have a reference for that it would be cool, NOT BECAUSE I DON'T TRUST YOU, but because I'm writing all of this and a reference may be need later so I'm trying to collect them
This is cool, because I have a lot of links now to reference this! Thank you guys!
I also tried to allocate in the stack memory by doing this:
Code:
void AllocateFromStack(long int bytes) {
char pool[bytes];
printf("It seems that allocating from the stack worked!\n");
pool[0] = 'a';
printf("It worked! pool[0] = %c\n", pool[0]);
}
and then calling it from the main module. At first I thought that I shouldn't work but I was surprised by finding out that it did! Because I could successfully allocate in execution time Now, should I be surprised? Is that true that pool, in this context is actually being allocated on the stack memory. I think so but I would like further insights!
This is cool, because I have a lot of links now to reference this! Thank you guys!
I also tried to allocate in the stack memory by doing this:
Code:
void AllocateFromStack(long int bytes) {
char pool[bytes];
printf("It seems that allocating from the stack worked!\n");
pool[0] = 'a';
printf("It worked! pool[0] = %c\n", pool[0]);
}
and then calling it from the main module. At first I thought that I shouldn't work but I was surprised by finding out that it did! Because I could successfully allocate in execution time Now, should I be surprised? Is that true that pool, in this context is actually being allocated on the stack memory. I think so but I would like further insights!
You better use 'unsigned' (and probably 'unsigned long') for 'bytes'. At all, unless you expect negatives values, use 'unsigned' - (signed) 'int' is actually rarely needed.
Yeah but it works until an specific value of "bytes"
In Linux, the maximum stack size is typically controlled by a setting in ulimit. It is often quite small (compared to what works for the size of a static or heap object).
Quote:
I'm still not sure if just by allocating pool inside a function like this:
actually causes for pool to be allocated in the stack memory.
I think you copied the wrong earlier example into that post.
I'm sure (at least for x86 and x86_64) the correct example (in post #5) does do stack allocation because I have stepped through equivalent code with a debugger and watched the stack allocation occur.
I'm pretty sure the C standard won't tell you that this type of allocation is on the stack, because even having a stack at all is an implementation detail. The C standard does not specify such implementation details.
I don't know if GCC documentation mentions that such variables are on the stack. It certainly doesn't mention its specific choice for most implementation details of the C standard.
You're right! I copied the wrong code as example! I meant the one that was quoted in post #5.
0k so, what about dynamic allocation within a function? It is of my understanding that every dynamic memory allocation takes resources FROM THE HEAP, but is this true even for functions? If I code this:
Code:
void AllocateFromStack(long int bytes) {
char *pool;
printf(" Called with %ld.\n", bytes);
pool = (char *) malloc (bytes);
if (pool != NULL) {
printf("It seems that allocating from the stack worked!\n");
pool[0] = 'a';
printf("It worked! pool[0] = %c\n", pool[0]);
} else {
printf("It seems that allocating from the stack DIDN't work!\n");
}
free(pool);
}
is pool being allocated on the stack or in the heap?
Last edited by ejspeiro; 02-08-2011 at 06:03 PM.
Reason: Extending with a question
It is of my understanding that every dynamic memory allocation takes resources FROM THE HEAP, but is this true even for functions?
Yes.
Quote:
is pool being allocated on the stack or in the heap?
Heap.
More exactly, pool is a pointer, which is 4 or 8 bytes long (x86 or x86_64). That 4 or 8 bytes is from the stack. That pointer points to a chunk of bytes characters allocated from the heap.
automatic variable is a lexically-scoped variable which is allocated and de-allocated automatically when program flow enters and leaves the variable's scope. The term local variable is usually synonymous with automatic variable, since these are the same thing in many programming languages.
Automatic variables may be allocated in the stack frame of the procedure in which they are declared; this has the useful effect of allowing recursion and re-entrancy. (For efficiency, the optimizer will try to allocate some of these variables in processor registers.)
A variable that has been allocated statically — whose lifetime extends across the entire run of the program. This is in contrast to the more ephemeral automatic variables (local variables), whose storage is allocated and deallocated on the call stack; and in contrast to objects whose storage is dynamically allocated.
The auto and register specifiers may only be used within functions and function argument declarations; as such, the auto specifier is always redundant.
...
Objects with automatic storage are local to the block in which they were declared and are discarded when the block is exited. Additionally, objects declared with the register storage class may be given higher priority by the compiler for access to registers; although they may not actually be stored in registers, objects with this storage class may not be used with the address-of (&) unary operator. Objects with static storage persist upon exit from the block in which they were declared. In this way, the same object can be accessed by a function across multiple calls. Objects with allocated storage duration are created and destroyed explicitly with malloc, free, and related functions.
The extern storage class specifier indicates that the storage for an object has been defined elsewhere. When used inside a block, it indicates that the storage has been defined by a declaration outside of that block. When used outside of all blocks, it indicates that the storage has been defined outside of the compilation unit. The extern storage class specifier is redundant when used on a function declaration. It indicates that the declared function has been defined outside of the compilation unit.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.