Stack vs Heap Memory

An exercise is to write a program that shows how memory is allocated to stack variables compared to heap variables. I ran the following code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "../../std_lib_facilities.h"

int main ()
{
   char c = ' ';
   char ch0[10];
   char *ch = new char[10];
   char *init_ch = ch;
   cout << "Enter characters separated by a space.\nUse the '!' to indicate the end of your entries." << endl;
	
   int i = 0;
   while (cin >> c) {
      if (c == '!') {
         break;
      } else {
	 *ch = c;
	 ch0[i] = c;
	 ch++;
	 i++;
      }
   }

   ch = init_ch;
   for (int i = 0; i < 10; i++) {
      cout << *ch << "  " << reinterpret_cast<void*>(ch) << endl;
      cout << ch0[i] << "  " << reinterpret_cast<void*>(&ch0[i]) << endl;
      cout << endl;
      ch++;
   }

   ch = init_ch;
   delete[] ch;

   keep_window_open();
   return 0;
}   


The output I get is an address of 00345A48 for the first element of the ch (heap) array, and an address of 0012FF48 for the first element of the ch0 (stack) array. The addresses of the other elements increase by 1 unit in both arrays.

The illustration in my book of the memory layout shows stack memory 'below' heap memory. I am guessing that means stack memory addresses will have smaller numbers than heap memory addresses, as my output shows.

Is that supposed to happen?

Thanks in advance for explanations.
I found several different illustrations of memory layout on the Web. Some of them explicitly show the stack above the heap. But the stack addresses decline, while the heap addresses increase.

Why does my output show stack addresses increasing?
OK. I answered my own question. I was printing the addresses of elements in an array, which always increase. I should have printed the addresses of different arrays. Subsequent arrays would have either higher or lower addresses. I ran a different program.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "../../std_lib_facilities.h"

int main ()
{
   char c = ' ';
   char ch0[10];
   char ch1[10];
   char *cha = new char[10];
   char *chb = new char[10];
   char *init_cha = cha;
   char *init_chb = chb;

   cout << "Enter characters separated by a space.\nUse the '!' to indicate the end of your entries." << endl;
	
   int i = 0;
   while (cin >> c) {
      if (c == '!') {
         break;
      } else {
	*cha = c;
	*chb = c;
	ch0[i] = c;
	ch1[i] = c;
	cha++;
	chb++;
	i++;
      }
   }  

   cha = init_cha;
   chb = init_chb;
   for (int i = 0; i < 10; i++) {
      cout << *cha << "  " << reinterpret_cast<void*>(cha) << endl;
      cout << *chb << "  " << reinterpret_cast<void*>(chb) << endl;
      cout << ch0[i] << "  " << reinterpret_cast<void*>(&ch0[i]) << endl;
      cout << ch1[i] << "  " << reinterpret_cast<void*>(&ch1[i]) << endl;
      cout << endl;
      cha++;
      chb++;
   }

   cha = init_cha;
   chb = init_chb;
   delete[] cha;
   delete[] chb;

   keep_window_open();
   return 0;
}   


My results are as expected. The address of the first element of cha, the first heap array, is 00345A48. The address of the first element of chb, the second heap array, is 00345A90. The address increased. The address of the first element of ch0, the first stack array, is 0012FF48. The address of the first element of ch1, the second stack array, is 0012FF34. The address decreased.

So the two types of memory are presumably working as they are supposed to. However, now I am confused as to how stack memory can be below heap memory and decrease addresses, while heap is above stack memory and increases addresses. Some of the illustrations from the Web show stack memory 'above' heap memory. I think I am misreading these illustrations.

What is the correct memory layout?
It's a bid more complicated then this but in general for a ARC based CPU 32 bit:

In 32bit the address go from 0 to 2^24 every block is 32bits

1
2
3
  A   1     B    2      X    3     C   4         D
______|__________|___________|_________|______________|
0    2^22                             2^23-4         2^24-4


A = Reserved for built-in bootstraps and graphics routines/memory
B = Working memory (heap)
X = unused free memory
C = stack memory
D= Reserved space for I/O controllers.

1 = bottom of the heap.
2 = top of the heap.
3 = top of the stack.
4 = bottom of the stack.

The heap and stack grow to each-other the heap starting a 2^22 and the stack at 2^23-4.

There is not on way of doing this, but this is the layout of a ARC CPU the address location and ordering may be different.
Last edited on
Thank you, Raggers.

Your explanation is clear and helped me understand this issue much better. It also suggests to me that different chip manufacturers have different memory layouts depending on the intended primary use for the chip. At least, that is the impression I am getting from searching about memory layout on the Web.

This has not been a popular tread. I am wondering if the topic is too arcane and unimportant. (I know there are plenty of very capable posters here who could give excellent explanations.) Stroustrup seems to believe that a professional programmer needs to understand how software and hardware interact with each other. One of the areas of interaction is memory. I think I now have a good enough foundation of this topic, upon which I can build a deeper understand as I learn more about programming in C++.
It is important in more advanced programming situations, like programming drivers or interfacing with hardware, or a must if you are doing assembler and low level languages. But for the more basic stuff its always good to know, but no must.

The stack and heap layout are standard to all CPU's, the other parts like I/O and graphics can differ from CPU to CPU. Keep in mind this is based on a ARC CPU build somewhere in the 90's. There are many new technologies and features that have been introduced since then, like 64bit, pipe-lining, multi-band memory, north/south bridges, and so on. Many of which effects the way memory is used by the CPU but the basic ARC layout can still be found in one form or an other.

As for this not being popular, having worked as a programmer I was surprised at how many programmers I worked with don't know this stuff. I don't know if it's the same with people here. I have a degree in Computer Architecture and organization, I had to refresh my memory too but this is all stuff I had to learn and even implement by building my own CPU.

If you really want to go deeper in to C++, I'd advise on learning how a compiler works and who it goes from a high level (C++) to a platform independent code to a low level code (assembler) and finally to executable binary. This is not easy stuff but it will give you a great inside in how C++ works and interacts with different platforms.
Topic archived. No new replies allowed.