Different Types of Memory Allocation

As I said earlier(which you don't need to remember), I am looking to clear my basic doubts so that I can move to advanced stuff and our C++ instructor did not sufficiently explain memory allocation.

I'll begin with the sequential type
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
#include<iostream>
#include<limits>

using namespace std;

const int arrsize = 80; //When is this destroyed?

int main()
{
	static int arr_size = 80; //These and the above are same. 
	int a[arrsize]={1,2,3,4,5,6};  //How is this stored? Does it get destroyed as I leave main() ?
	//	a[arrsize]={1,2,3,4,5,6} <------- Why is this wrong? Separate declaration and initialization
	for(int i=0; i<6; i++) 
	{
		cout<<a[i]<<"\t";
	}
	cout<<"\n";
	
	int* p = new int (100);  //I don't need to give the location a variable? Just (*p) is enough?
 	cout<<"p Has "<<p<<" and "<<*p; 
 	delete p; //What if I don't delete here?
 	
	//--------------------------------------------------------------//
	std::cout<<endl<< "Press ENTER to continue...";
	std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

  	return 0;
}
Do you have a question?
The question is hidden in the comments... Brahmnic Boy, please in the future make the actual question clearer.

const int arrsize = 80; //When is this destroyed?
For all practical matters, the 80 will just be a hardcoded value in the program, but technically, it is "destroyed" after main completes. This is easier to see with a non-trivial object.
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
// Example program
#include <iostream>
#include <string>

class Destruction {
  public:
    Destruction(std::string s)
    : s(s) {
        std::cout << "Constructing " << s << '\n';
    }
    
    ~Destruction()
    {
        std::cout << "Destructing " << s << '\n';   
    }
    
    std::string s;
};

Destruction global_destruction("globally");

int main()
{
    std::cout << "Hello, main\n";
    Destruction local_destruction("locally");
    std::cout << "Goodbye, main\n";
}

Constructing globally
Hello, main
Constructing locally
Goodbye, main
Destructing locally
Destructing globally


_____________________________________________

//How is this stored? Does it get destroyed as I leave main() ?
Automatic lifetime. Yes, it is destroyed when you leave main.

_____________________________________________

//I don't need to give the location a variable? Just (*p) is enough?
p is a variable. p is a pointer to some data. The data happens to be the data that was dynamically created with the new call. So no, this data itself is not a variable.

_____________________________________________

//What if I don't delete here?
The memory will continue to exist until your Operating System kindly cleans it up for you after the program ends.
Last edited on
const int arrsize = 80; //When is this destroyed?
it may not be created or destroyed. If optimize is on in a smart compiler, the value 80 is a constant at compile time that is injected into your code directly, without the need to create anything.

if it were instead not constant or the compiler were dumb about it, its at the global scope and is destroyed at the end of the program.

static int arr_size = 80; //These and the above are same.
no, they are not the same at all. this isnt constant. because its static, it is created at program start and destroyed at program end.

int a[arrsize]={1,2,3,4,5,6}; //How is this stored? Does it get destroyed as I leave main() ?
yes, it is created when main starts and destroyed when main ends.
it is pushed onto the stack, as a solid block of bytes. 6*sizeof(int) bytes are reserved to hold it all as one chunk.

// a[arrsize]={1,2,3,4,5,6} <------- Why is this wrong? Separate declaration and initialization
arrsize is not a constant here. That is wrong if this were to be a create statement. It is also missing a type if it were to be a create statement. There may be some new c++ way to do this, but as far as I know (someone else can correct me here) you can't assign arrays this way, you have to assign one location at a time after the variable creation. Its wrong because the language does not always support the syntax you would like for it to?



int* p = new int (100); //I don't need to give the location a variable? Just (*p) is enough?
p is a variable. You are not understanding your code here. You made a variable named p of type integer pointer.

delete p; //What if I don't delete here?
not much, due to the simple circumstances. If you were on a very simple special OS you could lose that memory until reboot of the machine. Modern full computer sized (including phone etc) OS will clean it up for you when the program ends, and since you are in main, there is no real harm done. It is still terrible to not delete it because that causes you to have a bad habit, and that bad habit will cause you to leak memory in more complex code (say you did this in some function other than main and called that function a few billion times... your machine would run out of memory and run slow, then crash after a while). Also, dynamic memory is avoided as much as possible in modern c++; the STL containers do most of it for us.
Last edited on
(6) const int arrsize = 80; //When is this destroyed?
Numeric constants don't necessarily use any memory at all. This is one such case, because you've only used the constant as a size for arrays.

(10) static int arr_size = 80; //These and the above are same.
Actually, no, they're not the same.
Since arr_size is never used, I think it's possible the compiler will optimize it away, but if you had used it somewhere, the compiler would have needed to reserve a little bit of memory for it, which would be released when the program terminates.

(11) int a[arrsize]={1,2,3,4,5,6}; //How is this stored? Does it get destroyed as I leave main() ?
It's stored on the stack, and yes, once main() returns a's memory will be released automatically.

a[arrsize]={1,2,3,4,5,6} <------- Why is this wrong? Separate declaration and initialization
There's two different conceptual errors here.

First, once an array has been declared, a[arrsize] refers to a single element of the array (actually, it erroneously refers to one element past the end of the array, but we'll ignore that for now). Therefore, this:
1
2
int a[arrsize];
a[arrsize]={1,2,3,4,5,6};
is wrong for the same reason that this is wrong:
1
2
int x;
x={1,2,3,4,5,6};

Second, arrays cannot ever be assigned directly. This would still be wrong:
1
2
int a[6];
a={1,2,3,4,5,6};

You can accomplish that by several different methods. For example:
1
2
3
int a[arrsize];
static const int data[] = {1,2,3,4,5,6};
std::copy(data, data + 6, a);


(19) int* p = new int (100); //I don't need to give the location a variable? Just (*p) is enough?
I don't understand the question.

(21) delete p; //What if I don't delete here?
If you never delete, you will leak memory. If you're just dealing with basic types and the program exits immediately, it's probably not a problem (although it's still bad form).
If you allocate memory in a loop and never delete it, you will eventually exhaust all the memory in the machine.
If you're dealing with non-trivial objects, not releasing them can have unpredictable effects that may or may not remain once your program has terminated.

In short, if you allocate memory you should release it. Better yet, don't use new and delete if you can avoid it, and always use containers and/or smart pointers.
OKay! Thanks, everyone.

It seems that I did not properly word the question on this one:

 
 int* p = new int (100);


What I mean is, generally we are taught to do this:

1
2
3
int i=4, *p;
p = &i;
//here p contains the address of the (memory location, aka House) named 'i' , containing 4 


What happens to the name of the house when we do
 
 int* p = new int (4);


new int (4) is dynamic memory (object with dynamic lifetime). It exists, it just doesn't have a name.
This dynamic memory is accessed through a pointer.

Think of it sort of like saying int foo = 40;
40 is an object (of type int), but it doesn't have a name. But its value is then stored into the foo variable.
new int(4) is an object (of type int*), but it doesn't have a name. But its value is then stored into the p variable.
Last edited on
int i=4, *p;
p = &i;

this is completely different. here you have a pointer to an existing piece of memory (your program already owns the memory where the variable 'i' is located). If you lose this kind of pointer, there is no problem, i is still managed in your code and no harm is done. You must not call delete on it. Delete and new go together as a pair just like {} braces or () etc : every new requires one delete, and you must not delete without a new.

new is asking for a piece of memory that you did not own before. Once you get it, it has no name, the pointer is all you know about it. You must keep this address in a variable until you call delete on it.
Topic archived. No new replies allowed.