Pointers to objects in C++ - what's on the stack/heap? - c++

I started out with Java, so I am a bit confused on what's going on with the stack/heap on the following line:
string *x = new string("Hello");
where x is a local variable. In C++, does ANYTHING happen on the stack at all in regards to that statement? I know from reading it says that the object is on the heap, but what about x? In Java, x would be on the stack just holding the memory address that points to the object, but I haven't found a clear source that says what's happening in C++.

Any object you just created, e.g. x in your example is on the stack. The object x is just a pointer, though, which points to a heap allocated string which you put on the heap using new string("Hello"). Typically, you wouldn't create a string like this in C++, however. Instead you would use
string x("Hello");
This would still allocate x on the stack. Whether the characters representing x's value also live on the stack or rather on the heap, depends on the string implementation. As a reasonable model you should assume that they are on the heap (some std::string implementation put short string into the stack object, avoiding any heap allocations and helping with locality).

yes, x is on the stack : it is a local variable, which are all on the stack.
The new operator provokes the allocation of memory on the heap.

It's the same as in Java. The string or String is on the heap, and the pointer (or reference, in Java) is on the stack.
In Java, all the Objects are on the heap, and the stack is only made up of primitive types and the references themselves. (The stack has other stuff like return addresses and so on, but never mind that).
The main difference between the C++ stack and the Java stack is that, in C++, you can put the entire object directly onto the stack. e.g. string x = string("Hello");
It's also possible, in C++, to put primitive types directly onto the heap. e.g. int * x = new int();. (In other words, "if autoboxing is the solution, then what was the problem?")
In short, Java has rigid distinctions between primitive types and Objects, and the primitives are very much second-class. C++ is much more relaxed.

It depends on where this line is located. If it is located somewhere at file scope (i.e. outside of a function), then x is a global variable which definitely is not on the stack (well, in theory it could be put on the stack before calling main(), but I strongly doubt any compiler does that), but also not on the heap. If, however, the line is part of a function, then indeed x is on the stack.
Since x is of type string* (i.e. pointer to string), it indeed just contains the address of the string object allocated with new. Since that string object is allocated with new, it indeed lives on the heap.
Note however that, unlike in Java, there's no need that built-in types live on the stack and class objects live on the heap. The following is an example of a pointer living on the heap, pointing to an object living in the stack:
int main()
{
std::string str("Hello"); // a string object on the stack
std::string** ptr = new std::string*(&str); // a pointer to string living on the heap, pointing to str
(**ptr) += " world"; // this adds "world" to the string on the stack
delete ptr; // get rid of the pointer on the heap
std::cout << str << std::endl; // prints "Hello world"
} // the compiler automatically destroys str here

Related

Only the stack can store local (pointer) variables, not Heap?

I am new to C and C++. I understand that whenever a function is called, its variables get memory allocated on the stack, that includes the case where the variable happens to be a pointer that points to data allocated on the heap via malloc or new (but I heard it is not guaranteed that the storage allocated by malloc is 100% on the Heap, please correct me if I am wrong). For example,
Void fn(){
Member *p = new Member()
}
Or
Void fn() {
int *p = (int*) malloc( sizeof(int) * 10 );
}
Please correct if I am wrong, in both cases, variable p (which holds the address to the object allocated on the heap) is on the stack, and it points to the object on the heap.
So is it correct to say that all the variables we declare are on the stack even though they might point to something on the heap?
Let’s say the address of local variable pointer p is loaded at memory address 001, it has the address of the member object located on Heap, and that address is 002. We can draw a diagram like this.
If that is correct, my next question is, can we have a pointer that is actually located on the heap, and it points to a variable located on Stack? If it is not possible, can that pointer points to a variable located on Heap?
Maybe another way to phrase this question is: in order to access something in heap, we can only access it via pointers on the stack??
A possible diagram could look like this
If that is possible, Can I have an example here?
Yes, you can put your pointer on the free store (heap) and have it point to a variable on the stack. The trick is to create a pointer to a pointer (int**):
int main()
{
int i = 0; // int on the stack
int** ip = new int*; // create an int* (int pointer) on the free store (heap)
// ip (the int**) is still on the stack
*ip = &i;
// Now your free store (heap) located pointer points
// to your stack based variable i
delete ip; // clean up
}
NOTE: The terms "heap" and "stack" are general, well understood, computing terms. In C++ they are referred to in the Standard as the "free store" and (although not directly named) a "stack" is 100% implied (eg. through references to "stack-unwinding") and therefore required.
stack and heap are not specifically defined by the standard. Those are implementation details.
Heap refers to a data structure that many operating systems use to help them safely manage the allocated space for different programs running at the same time. Read more here
Here is a diagram for a simple heap so that you can have a mental model of it:
Keep in mind that this is not exactly what operating systems use. In fact, operating systems use a far more advanced form of the heap data structure that allows them to perform many sorts of complex memory-related tasks. Also, not every OS implements the free store using the heap data structure. Some may use different techniques.
Whereas a stack is much simpler:
can we have a pointer that is actually located on the heap, and it points to a variable located on Stack?
Yes, it's possible but rarely needed:
#include <iostream>
int main( )
{
int a_variable_on_stack { 5 };
int** ptr_on_stack { new int*( &a_variable_on_stack ) };
std::cout << "address of `a_variable_on_stack`: " << &a_variable_on_stack << '\n'
<< "address of ptr on the heap: " << ptr_on_stack << '\n'
<< "value of ptr on the heap: " << *ptr_on_stack << '\n';
std::cin.get( );
}
Possible output:
address of `a_variable_on_stack`: 0x47eb5ffd2c
address of ptr on the heap: 0x1de33cc3810
value of ptr on the heap: 0x47eb5ffd2c
Notice how the address of a_variable_on_stack and value of ptr stored on heap are both 0x47eb5ffd2c. In other words, a pointer on the heap is holding the address of a variable that is on the stack.
In short:
Variables declared within a function are allocated on the stack, and can point to whatever you want (to address of other variables on the stack and to address of other variables on the heap).
Same is for variables declared on the heap. They can point to address of other variables on the heap or to address of variables on the stack. There is no limitation here.
However, variables declared on the stack, are by nature temporary, and when function return this memory is reclaimed. Therefor it is not a good practice to have pointers to variable's address at the stack, unless you know the function did not finish yet (i.e. using local variables address from within the same function or by functions calls from within the same function). A common mistake of novice C/C++ developers, is to return from function, address of variable declared on the stack. When function returns, this memory is reclaimed and will be soon reused for other function calls memory, so accessing this address has undefined behavior.
I am new to C and C++.
Your question is not C or C++ specific, but it is about programming languages in general.
... whenever a function is called, its variables get memory allocated on the stack ...
This is correct: Nearly all compilers do it this way.
However, there are exceptions - for example on SPARC or TriCore CPUs, which have a special feature...
... allocated on the heap via malloc ...
malloc never allocates memory on the stack but on the heap.
... is not guaranteed that the storage allocated by malloc is 100% on the heap ...
Unlike the word "stack", the meaning of the word "heap" differs a bit from situation to situation.
In some cases, the word "heap" is used to specify a certain memory area that is used by malloc and new.
If there is not enough memory in that memory area, malloc (or new) asks the operating system for memory in a different memory area.
However, other people would also call that memory area "heap".
... in both cases, variable p is on the stack, and it points to the object on the heap.
This is correct.
... can we have a pointer that is actually located on the heap, and it points to a variable located on Stack?
Sure:
int ** allocatedMemory;
void myFunction()
{
int variableOnStack;
allocatedMemory = (int **)malloc(sizeof(int *));
*allocatedMemory = &variableOnStack;
...
}
The variable allocatedMemory points to some data on the heap and that data is a pointer to a variable (variableOnStack) on the stack.
However, when the function myFunction() returns, the variable variableOnStack does no longer exist. Let's say the function otherFunction() is called after myFunction():
void otherFunction()
{
int a;
int b;
...
}
Now we don't know if *allocatedMemory points to a, to b or even the "return address" because we don't know which of the two variables is stored at the same address as variableOnStack.
Bad things may happen if we write to **allocatedMemory now...
In order to access something in heap, we can only access it via pointers on the stack??
... diagram "B" ...
To access some data on the heap, you definitely need some pointer that is not stored on the heap.
This pointer can be:
A global or static variable
In my example above, allocatedMemory is a global variable.
Global and static variables are neither stored in a completely different memory area (not heap nor stack)
A local variable on the stack
A local variable in a CPU register
(I already wrote that local variables are not always stored on the stack)
Theoretically, the situation in diagram "B" is possible: Simply overwrite the variable allocatedMemory by NULL (or another pointer).
However, a program cannot directly access data on the heap.
This means that p* (which is some data on the heap) cannot be accessed any more if there is no more pointer "outside" the heap that points to p*.

Is dynamic memory allocation be done by pointers [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
dynamic memory allocation by pointers
what is the link between pointers and dynamic memory allocation . why do we use pointers for
dynamic memory allocation . whenever we use new operator we use only pointer variables why?
can anyone explain with an example
According to your question to start with you need not programming but real life example.
Imagine you live in your ordinary flat, it has its own address and on the door you can see big sign "Robin Mandela". It's like static memory allocation. On the start of your program you have some room in memory and a name associated with it. On every vacation you fly to other country where you rent a room in a hotel. You can live one year in one room, another year in another room and even change room during your vacation. You may even not really be interested in what room exactly you will live in, but you need to know that you precisely will have one to live in.
When you ask for dynamic memory allocation, you get some portion of memory. This memory can be allocated almost anywhere, like a room in hotel, and of course you need a key with number to know where to find it. A pointer is like that number on the key - it grants you access to your allocated data.
Also one year you may decide not to go on vacation and rent a room at all. You can't do this with your flat - you have just got it, live there or not. It's like static memory in program.
The size and location (memory address) of objects of automatic and static storage duration is known at compile time. The objects can be accessed through variables and the compiler handles the memory implicitly.
Dynamic memory on the other hand, is allocated at run time, as the name implies. Because it happens at runtime, the compiler can not have knowledge of where the memory is allocated and therefore can not handle the memory for the you. You must access the memory using it's address.
How to get the address of dynamically allocated memory?
It is returned by the new operator which allocates the memory and constructs the object. Since using dynamic memory just in one statement is not useful, you must store the address in a variable.
What type of variable can store a memory address of an object?
A pointer type. The type of the return value of a new-expression is a pointer to the type of object you constructed.
An example:
void foo() {
Foo f; // The object of type Foo has automatic storage and can be accessed through the variable `f`.
Foo* f_ptr; // The pointer object has automatic storage and is not yet initialized.
new Foo; // Bad! The dynamically allocated memory can not be accessed in any way (it has leaked).
f_ptr = new Foo; // The address of another dynamically allocated object is assigned to the f_ptr variable. The object is accessible through this pointer.
delete f_ptr; // Dynamically allocated objects must be deleted explicitly.
// f and f_ptr are destroyed automatically when the scope ends. If the memory pointed by f_ptr was not deleted before this, the memory would leak.
}
The question itself is a bit nonsensical. The keyword new is for allocating memory on the heap and returns either a pointer to the allocated object or throws a std::bad_alloc if allocation fails. It's in a sense like asking why int main(int argc, char** argv) returns an int.
In C++ you have two address spaces to work with; the stack and the heap.
Generally you want to use the heap for allocating your objects and pass them to functions either by reference, the preferred way, or by pointer. In some cases you can't use the stack, mainly when you either don't know how long the object you are creating is going to be alive or when you know that the object should live longer than the scope that creates it. For those cases you should be using std::unique_ptr or std::shared_ptr if you are using C++11 since the object will be deleted automatically when it's no longer needed.
Use of the keyword new is generally discouraged and should only be used when you're certain that neither of the above works.
To read up on the operator new:
cppreference.com
wikipedia
shared_ptr:
cppreference.com
Difference between stack and heap:
learncpp.com
The function you use (for example: malloc() in c) try to get a part of the memory with the length you asked and then it gives you the address of this part of the memory if the allocation was successful else it gives you a 0 (in c and c++ at least).
(When you want to have memory for an array of n items, you must ask for n * item size and you will get the address of the array which is also the address of the first element of your array in fact.)
Example: I want an array of 10 integers
// ask for allocation and get the address of the memory
int * my_array = (int *)malloc(10*sizeof(int));
// you must verify that the allocation was successful
if(my_array != 0) {
// the system gave you the memory you need
// you can do your operations
// " * my_array " and " my_array[0] " have the same meaning
my_array[0] = 22;
* my_array = 22;
// This two lines make the same thing : the put 22 in the memory at the adresse my_array
// same thing for " *(my_array + 9*sizeof(int)) " and " my_array[9] "
my_array[9] = 50;
*(my_array + 9*sizeof(int)) = 50;
// This two lines make the same thing : the put 50 in the memory at the adresse my_array + 36
// 36 = 9*4 (sizeof(int) = 4 in most cases)
free(my_array); //always free the memory to give back the memory to the system and do not "lost it"
}
It is the same in c++ but you replace malloc by new and free by delete. They are keyword but you can see them as functions to understand what it is done.

Where are pointers in C++ stored, on the stack or in the heap?

I am trying to understand the difference between the stack and heap memory, and this question on SO as well as this explanation did a pretty good job explaining the basics.
In the second explanation however, I came across an example to which I have a specific question, the example is this:
It is explained that the object m is allocated on the heap, I am just wondering if this is the full story. According to my understanding, the object itself indeed is allocated on the heap as the new keyword has been used for its instantiation.
However, isn't it that the pointer to object m is on the same time allocated on the stack? Otherwise, how would the object itself, which of course is sitting in the heap be accessed. I feel like for the sake of completeness, this should have been mentioned in this tutorial, leaving it out causes a bit of confusion to me, so I hope someone can clear this up and tell me that I am right with my understanding that this example should have basically two statements that would have to say:
1. a pointer to object m has been allocated on the stack
2. the object m itself (so the data that it carries, as well as access to its methods) has been allocated on the heap
Your understanding may be correct, but the statements are wrong:
A pointer to object m has been allocated on the stack.
m is the pointer. It is on the stack. Perhaps you meant pointer to a Member object.
The object m itself (the data that it carries, as well as access to its methods) has been allocated on the heap.
Correct would be to say the object pointed by m is created on the heap
In general, any function/method local object and function parameters are created on the stack. Since m is a function local object, it is on the stack, but the object pointed to by m is on the heap.
"stack" and "heap" are general programming jargon. In particular , no storage is required to be managed internally via a stack or a heap data structure.
C++ has the following storage classes
static
automatic
dynamic
thread
Roughly, dynamic corresponds to "heap", and automatic corresponds to "stack".
Moving onto your question: a pointer can be created in any of these four storage classes; and objects being pointed to can also be in any of these storage classes. Some examples:
void func()
{
int *p = new int; // automatic pointer to dynamic object
int q; // automatic object
int *r = &q; // automatic pointer to automatic object
static int *s = p; // static pointer to dynamic object
static int *s = r; // static pointer to automatic object (bad idea)
thread_local int **t = &s; // thread pointer to static object
}
Named variables declared with no specifier are automatic if within a function, or static otherwise.
When you declare a variable in a function, it always goes on the stack. So your variable Member* m is created on the stack. Note that by itself, m is just a pointer; it doesn't point to anything. You can use it to point to an object on either the stack or heap, or to nothing at all.
Declaring a variable in a class or struct is different -- those go where ever the class or struct is instantiated.
To create something on the heap, you use new or std::malloc (or their variants). In your example, you create an object on the heap using new and assign its address to m. Objects on the heap need to be released to avoid memory leaks. If allocated using new, you need to use delete; if allocated using std::malloc, you need to use std::free. The better approach is usually to use a "smart pointer", which is an object that holds a pointer and has a destructor that releases it.
Yes, the pointer is allocated on the stack but the object that pointer points to is allocated on the heap. You're correct.
However, isn't it that the pointer to object m is on the same time
allocated on the stack?
I suppose you meant the Member object. The pointer is allocated on the stack and will last there for the entire duration of the function (or its scope). After that, the code might still work:
#include <iostream>
using namespace std;
struct Object {
int somedata;
};
Object** globalPtrToPtr; // This is into another area called
// "data segment", could be heap or stack
void function() {
Object* pointerOnTheStack = new Object;
globalPtrToPtr = &pointerOnTheStack;
cout << "*globalPtrToPtr = " << *globalPtrToPtr << endl;
} // pointerOnTheStack is NO LONGER valid after the function exits
int main() {
// This can give an access violation,
// a different value after the pointer destruction
// or even the same value as before, randomly - Undefined Behavior
cout << "*globalPtrToPtr = " << *globalPtrToPtr << endl;
return 0;
}
http://ideone.com/BwUVgm
The above code stores the address of a pointer residing on the stack (and leaks memory too because it doesn't free Object's allocated memory with delete).
Since after exiting the function the pointer is "destroyed" (i.e. its memory can be used for whatever pleases the program), you can no longer safely access it.
The above program can either: run properly, crash or give you a different result. Accessing freed or deallocated memory is called undefined behavior.

C++ std::string* s; Memory reclaimed?

Given a function foo with a statement in it:
void foo() {
std::string * s;
}
Is memory reclaimed after this function returns?
I am assuming yes because this pointer isn't pointing to anything but some people are saying no - that it is a dangling pointer.
std::string* s is just an uninitialized pointer to a string. The pointer will be destroyed when function foo returns (because the pointer itself is a local variable allocated on the stack). No std::string was ever created, hence you won't have any memory leak.
If you say
void foo() {
std::string * s = new std::string;
}
Then you will have memory leak
This code is typical when people learn about strings a-la C, and then start using C++ through C idioms.
C++ classes (in particular standard library classes) treat objects as values, and manage themselves the memory they need.
std::string, in this sense is not different from an int. If you need a "text container", just declare an std::string (not std::string*) and initialize it accordingly (uninitialized std::strings are empty by definition - and default constructor) than use it to form expression using method, operators and related functions like you will do with other simple types.
std::string* itself is a symptom of a bad designed environment.
Explicit dynamic memory in C++ is typically used in two situation:
You don't know at compile time the size of an object (typical with unknown size arrays, like C strings are)
You don't know at compile time the runtime-type of an object (since its class will be decided on execution, based on some other input)
Now, std:string manage itself the first point, and does not support the second (it has no virtual methods), so allocating it dynamically adds no value: it just adds all the complication to manage yourself the memory to contain the string object that is itself a manager of other memory to contain its actual text.
This code just creates a pointer to somewhere in memory, which contains string value and it points to somewhere which has been allocated before and it does not allocate new string.
it just allocate a memory for pointer value and after function return it's no more valid...

Strings in memory

struct Example
{
char* string;
int x;
};
When I allocate a new instance of Example 8 bytes are allocated (assuming that sizeof(char*)=4). So when I call this:
Example* sp = new Example();
sp->string = "some text";
How is the string allocated? Is is placed in a random empty memory location? or is there some kind of relation between sp and member string?
So, "some text" makes a dynamic memory allocation?
String literals like that are put wherever the compiler wants to put them, they have a static storage duration (they last for the life of the entire program), and they never move around in memory.
The compiler usually stores them in the executable file itself in a read-only portion of memory, so when you do something = "some text"; it just makes something point to that location in memory.
The string is in the executable when you compile it.
sp->string = "some text";
This line is just setting the pointer in the struct to that string. (note: you have a double typo there, it's sp, and it's a pointer so you need ->)
In this case, the constant string value should be put into the program's data area, and the pointer in your struct will point to that area rather unambiguously as long as it has the value. In your words, it is placed into a random area of memory (in that it is unrelated to where your struct instance goes).
this way you made a string "CONSTANT" first, it stays in the program's heap (but not stack), You needn't manage it (alloc the memory of free it), and it can not be dynamically freed indeed.