Reputation: 278
These are mostly compiler design questions. When your compiler compiles this, for example:
int * pData = new int[256];
How is the memory allocated on-the-fly? Does the compiler make a call to an OS routine that allocates memory for you or is a function compiled that allocates the memory for you?
Also, when you write something like this:
if (x == 5)
int y;
Since the memory is not allocated at runtime, I'm assuming that the data takes up some room in the data segment of the program. Since the compiler can't really determine whether or not the int y;
branch will be executed at runtime, is the memory reserved for the variable whether or not int y;
is executed? And if it's reserved regardless, isn't it more memory-efficient to mem alloc any variables that are in a block that may or may not be executed?
o.o thanks
Upvotes: 4
Views: 5362
Reputation: 90422
For the first question: When the new
operator is encounter by the compiler like in your example:
int * pData = new int[256];
It effectively emits code which looks like this:
int *pData = reinterpret_cast<int*>(::operator new(256 * sizeof(int)));
// the compiler may also choose to reserve extra space here or elsewhere to
// "remember" how many elements were allocated by this new[] so delete[]
// can properly call all the destructors too!
If a constructor should be called, that is emitted as well (in this example, no constructor is called I believe).
operator new(std::size_t)
is a function which is implemented by the standard library, often, but not always, it will boil down to a malloc
call.
malloc
will have to make a system call, to request memory from the OS. Since OS allocators usually work with larger fixed sized blocks of memory, malloc
will not have make this call every time, only when it has exhausted the memory it currently has.
For the second question: For local variables, it really is up to the compiler. The standard makes no mention of a stack. However, most likely you are on a common architecture running a common OS and using a common compiler :-).
So for the common case, the compiler will typically reserve space at the beginning of the function call for all local variables by adjusting the stack accordingly or reserving registers for them if it can (a register being the preferred choice since it is much faster).
Then (in c++), when the variable is encountered, it will call the constructor. It could in theory, adjust the stack on an as needed basis, but this would be complicated to prove correct and less efficient. Typically reserving stack space is a single instruction, so doing it all at once is pretty optimal.
Upvotes: 6
Reputation: 437366
For the first question:
The compiler generates code to call the function operator new
, which itself usually calls malloc
from the C runtime library, which itself makes a call to some OS-specific library which (you can see where this is going) at some point ends up switching into kernel mode and allocating memory for the process.
In any case, the native code which the compiler generates for your own program does not make the allocation itself.
For the second question:
The memory for int y
is allocated on the stack. Regardless of whether the condition is true, in the simplest, non-optimizing case the stack space allocation will happen each and every time control enters your function.
Since stack allocation is just a few register operations that take the same time no matter how much space is to be allocated, and since the memory will be reclaimed as soon as your function returns, there is no "memory hog" problem here.
Upvotes: 0
Reputation: 224864
How is the memory allocated on-the-fly? Does the compiler make a call to an OS routine that allocates memory for you or is a function compiled that allocates the memory for you?
In most implementations, it's a bit of a combination of those two. There is normally an operating system service that is used to provide blocks of memory to your process, and also some code in the runtime or the standard library that manages those blocks of memory on a finer-grained scale inside your application.
is the memory reserved for the variable whether or not "int y;" is executed? And if it's reserved regardless, isn't it more memory-efficient to mem alloc any variables that are in a block that may or may not be executed?
Normally, no - the space for y
would be allocated only if the appropriate code were executed. Variables with automatic storage class are normally on the stack, so making space for them is as easy as modifying the stack pointer. That said, the compiler can do pretty much whatever it wants in this case, so inspecting the output from your toolchain is the only way to know for sure.
Upvotes: 2
Reputation: 5414
With regards to your second question, that variable in the conditional code is an automatic variable. Generally those are allocated on the stack. In this case a good compiler would notice it is never read from or written to and not even bother allocating space on the stack for it.
Upvotes: 1
Reputation: 6387
Case 1: it will call an OS routine to allocate memory on the heap. The OS manages the memory.
Case 2: this is allocated on the stack. The stack is preallocated to your process and is used for local variables and functions arguments.
Upvotes: 0
Reputation: 23268
It really depends on the compiler for the 2nd example which is why we have the volatile keyword (in case we map variables to addresses which change) or it might just give you a warning but I'm fairly certain it will include it into your program (sometimes you want to increase the stack size of your method for hackish reasons). The first example in essence calls malloc(256 * sizeof(int)) and returns a pointer to that segment.
Upvotes: 0
Reputation: 392921
Local variables (int y) are allocated on the stack.
The same thing goes for the pointer, however the 'new'-ed expression is allocated on the heap, usually through a malloc call of sorts. The exact method and heap layout are implementation-defined.
Only global static data are in the data-segment.
The example int y will be optimized out because it isn't used.
Unlike e.g. C#, C++ is not allowed to reduce the scope for a variable so wrapping a shortlived local in { SomeClass y; } could help, so it gets destructed earlier
However, I'm pretty sure that for simple types (like int) no such restriction exists, because there can never be a destructor for those
Upvotes: 1