0

Noob here and I have 2 questions.

1) When creating an array like this int a[10], how does the system setup memory for the array? i.e. Does the system allocate ten 1-word memory contiguously (in heap?). What about char a[10]? or user defined type?

2) What about dynamic allocation? Such as int *a = new int[10]; How is this array setup in memory? (similar questions to question 1).

5
  • we can explain it here but you should get some books first, like Deitel. C/C++ takes your data type (int, char, etc) and allocates n-1 spaces in memory, each one with the same space: the one your compiler says. It can be 4bytes for one integer, it may be 2bytes, depends on compiler implementation. For dynamic, it is the same. But on that instruction your are allocating space for a pointer, too. Commented Dec 1, 2012 at 21:27
  • possible duplicate of quick question about memory management in C/c++ Commented Dec 1, 2012 at 21:30
  • @JerryCoffin: I can't in good conscience close specific, answerable questions as a duplicate of a NaRQ. :) Commented Dec 1, 2012 at 21:34
  • @cHao: Then vote to reopen the other (which really shouldn't have been closed as nARQ, IMO). Commented Dec 1, 2012 at 21:36
  • @JerryCoffin: Yes, it should have been closed. It was a steaming pile of a question. I mean, "...where does variable stay? What is stack, heap for? When malloc, what part of memory is been allocate? to where?" seems to me the very definition of "overly broad" and "vague". Commented Dec 1, 2012 at 21:39

2 Answers 2

4

This behaviour is not guaranteed by the C++ standard - it doesn't even mention the stack or heap.

But typically, when you call a function, a stack frame is pushed on to the stack that is large enough to contain all of that function's automatic variables (and other objects, such as its return value). So if you consider the function foo:

void foo() { int x; std::string str; } 

When this function is called, the top of the stack is pushed up so there is enough space for an int and a std::string. The size of those types are implementation-defined, with some restrictions placed on them by the standard, but you can just think of them as sizeof(int) and sizeof(std::string) bytes.

Now when you have an array in your function, such as int a[10], the stack frame for the function will contain enough space for 10 ints, or 10*sizeof(int) bytes. This frame size is baked right into your executable - when the function is called, the stack will increase by that size.

When you do dynamic allocation, such as int* a = new int[10], you are allocating space for 10 ints, or 10*sizeof(int), in the heap. However, you have increased the stack frame by some amount, namely sizeof(int*). The pointer object itself is stored on the stack but the ints that it points to are on the heap.

Note that in the first example, you may wonder how the stack frame size could be baked into the executable if an std::string can have variable length. That's because the std::string object itself has a fixed size, sizeof(std::string), but most likely does some kind of dynamic allocation to manage its internal representation - this internal representation will be on the heap.

Sign up to request clarification or add additional context in comments.

1 Comment

Just to make it clearer: All of this is not guaranteed by the standard and compilers actually do use this freedom to for example share stackspace between different variables. For example if you have two local integers whose lifetime doesn't overlap the compiler may very well only allocate enough space for one integer.
1
  1. You will get a 10 * sizeof(type) byte storage block on the stack (assuming no overflow occurs), so each element in memory is contiguous and the same size, which is why pointer arithmetic for the elements of an array works. Once out of scope, this memory is deallocated. Note that this memory will not necessarily be initialized for you. In the case of int[10], it would contain junk, not 0s.

  2. It's the same, but the elements are on the free store, not the stack. new throws an exception if it cannot allocate the memory. new[] can also be overloaded. Once delete[] is called, this memory is deallocated, which is why something like std::vector is usually a better choice, because it deallocates it when the vector goes out of scope, among making some other aspects of using it easier.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.