1

I want to know the difference between dynamic memory, stack memory and static memory in C++.
Here is some code as an example:

#include<iostream>
using namespace std;
char *GetMemory(void)
{
    char p[]="hello world";
    char *q="hello world"; 
    return q;
}
int main(void)
{
    return 0;
} 

Why is p in the stack memory, but the q in dynamic memory?

Makoto
  • 104,088
  • 27
  • 192
  • 230
alan.chen
  • 2,115
  • 3
  • 15
  • 13

3 Answers3

1

why is the the "p" in the stack memory but the "q" in the dynamic memory?

That's not true; both p and q are allocated with automatic storage duration (implemented as a stack structure). The differences between them are:

  1. p is an array and points to modifiable memory (stack allocated).
  2. q is a pointer and points to readonly memory that has been allocated statically. You really should have declared it as:

    const char *p = "whatever";

There is no dynamic allocation here. You didn't call new, malloc, or some routine which uses those behind the scenes to allocate memory. As a result, it is incorrect to return p from this function as it will be invalid once the function returns.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • A bit of clarification: The point of declaring `const char *p` is to generate compiler warning when we try to modify the data that `p` points to. Without this, one will only notice the error of modifying readonly memory when the program runs and get a segfault. – nhahtdh Jul 23 '12 at 03:33
1

p and q are both variables. p is of type "array of 12 char" and q is of type "pointer to char". Both p and q have automatic storage duration. That is, they are allocated on the stack.

q is a pointer and it is initialized to point to the initial character of the string "hello world". This string is a string literal, and all string literals have static storage duration.

p is an array, so when you initialize p with a string literal, it causes p to declare an array of characters, and when it is initialized, the contents of the string literal are copied into the array. So, when GetMemory() is called, space is allocated on the stack for the array p, and the contents of the string literal "hello world" are copied into that array.

No dynamic allocation is performed by your code.


Note that because q is a pointer to an array of characters that have static storage duration, it is safe to return q from the function: the array to which it points will exist for the entire duration of the program. It would not be safe to return p, however, because p ceases to exist when the function returns.

Note also that the type of "hello world" is char const[12]. There is an unsafe implicit conversion in C++ that allows a string literal to be converted to a char* pointing to the initial character of the string literal. This is unsafe because it silently drops the const-qualification. You should always use const char* when handling string literals, because the characters are not modifiable. (In the latest revision of the C++ language, C++11, this unsafe conversion has been removed.)

James McNellis
  • 348,265
  • 75
  • 913
  • 977
0

For your examples, since you are using a string literal, this is likely written into the DATA segment of the executable. There is no dynamic memory allocated. A better example is something like this:

void foo()
{
    //This is a stack variable. Space is allocated 
    //on the stack to store it. Its lifetime is
    //the routine that calls it.

    some_class stack_variable; 

    //This is a heap-allocated variable. It will
    //remain in memory indefinitely unless deleted.
    //If a pointer to this isn't returned, and it
    //isn't deleted by the end of the routine, this
    //will become a "memory leak".

    another_class *heap_variable = new another_class();

    //This is a (method) static variable. It retains its
    //value between method calls

    static int method_static = 1;
    ++method_static;

} 

At the closing brace, stack_variable is cleaned up (that is, the stack space it occupied is reclaimed). heap_variable hasn't been deleted, and thus is a memory leak. If we call this method a few times:

for(int i = 0; i < 5; ++i) { foo(); }

Then method_static will have a value of 5.

Yuushi
  • 25,132
  • 7
  • 63
  • 81