Implicit memory allocation and initialization when declaring a pointer [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Declaring a pointer to struct in C++ automatically allocates memory for its members. Am I wrong?
Say if I define the structure Human as:
struct Human{int year, Human* Mom};
does the expression
Human* Bob;
automatically allocate a memory for both Bob and the Human object it is pointing to?
Because I noticed that
Bob == NULL
is false;
Does this mean that the above expression creates a static memory of the object Human?
Also, I noticed that
Bob->year
is NOT initialized to 0 automatically, but
Bob->Mom
is being initialized to NULL, why is that?
Another thing, if I allocate the memory dynamically, e.g.
Human* Bob = new Human;
Then I found that
Bob->Mom
is no longer NULL, how this is happening?

At minimum, the structure declaration should be corrected to:
struct Human { int year; Human *Mom; };
The statement:
Human *Bob;
then creates a storage location, but does not initialize it if it is created inside a function. If it is at global scope, it would be initialized to zero (NULL), but you say Bob == NULL is false, so it must be an uninitialized local variable. It doesn't point at anything. Any use of it other than as the target for an assignment invokes undefined behaviour because the value in Bob is undefined.
No; the definition shown does not allocate storage for Bob to point at.
Your other observations all depend on the quirks of your runtime system. Because the behaviour is undefined, anything can happen and it is 'OK' according to the standard. You need a default constructor for the type to get the values set sensibly when you use:
Human *Bob = new Human;
You have not provided one, and the system doesn't need to provide one, so the object pointed at is uninitialized.

No, it doesn't allocate memory. Bob is a pointer with garbage value, so who knows what it's pointing to.

does the expression Human* Bob; automatically allocate a memory for both Bob and the Human object it is pointing to? Because I noticed that Bob==NULL is false; Does this mean that the above expression creates a static memory of the object Human?
No, it doesn't. Bob is not initialised, so will just point to some random garbage. You must explicitly allocate memory for Bob.
Another thing, if I allocate the memory dynamically, e.g. Human* Bob=new Human; Then I found that Bob->Mom is no longer NULL, how this is happening?
As above, uninitialised memory could have anything in it. Trying to follow the pointer will lead to disaster. Good practice is to initialise all pointers to NULL or to immediately point them at an allocated block of memory.

In your code, the only instruction you have given to the compiler is to create a pointer (either a 32 bit or 64 bit variable) which you intend to point to a structure of type "Human".
Since you have not initialized the pointer, its value is most likely what was in that memory space - that could be a 0 (NULL), or anything else.
When you call Bob->Mom, you are dereferencing the pointer (Bob) and looking at an area in memory that is arbitrary (potentially a space you are not allowed access to). You most likely will get a segmentation fault (on a *nix machine).
What you should do is:
Human* Bob = new Human();
That will create dedicated space for the structure and return the address of that structure and assign it to the pointer Bob. Now, when you dereference Bob, it will actually point to a space which has been allocated specifically for the Human structure.

Its your responsibility to initialize pointer values. Unless you have set them to something (like 0 or NULL), their value is undefined and you may get a different uninitialized pointer value with each corresponding allocation.
In terms of allocation, you have defined a recursive or self-referential data structure. Consider what happens if it in fact did allocate memory for an additional Human for the Mom member; it would then have to allocate another Human for Bob->Mom->Mom and so on...
So, no. Only one Human is allocated. Any native pointer is just a memory address location, nothing more.
You can make pointer initialization easier on yourself if you use a constructor:
struct Human {
int year;
Human *Mom;
Human() : year(0), Mom(NULL) {}
};

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*.

Confused between structures and strucutre pointers

I wanted to know the difference between
struct file_operations {
} a;
and
struct file_operations {
} *a;
As in how are they allocated in memory? How does the compiler know about the memory location of 'a' in the first case? Is it from symbol table? If so how is address to symbol table(or any other table) found?
In the second case I'm assuming the memory address gets stored in a variable of size 32 bits , how is this variables location(address of 'a' in second code) figured out?
In the first case, an instance of the structure is allocated in memory, the ammount of bytes allocated equals the value returned by sizeof(a).
In the second case a pointer is allocated, the ammount of bytes allocated equals the size of a pointer i.e. sizeof(void *).
As you might be guessing, the second case doesn't allow you to access the fields of the structure, becuase the memory the pointer points to, is invalid until you request enough memory from the heap, or until you make it point to an instance like the one in your first example.
Suppose that we had the following structure
struct Data {
int quantity;
double value;
char name[100];
};
If you do the following
struct Data data;
then an instance of struct Data is allocated, you can access it's fields immediately, for example
data.quantity = 1;
data.value = 3.0;
strcpy(data.name, "My Name Is ...");
If you declare a pointer, like
struct Data *pointer;
then you can't access the fields until you make the pointer point to a valid instance of struct Data, otherwise undefined behavior will happen, you can create such instance by just taking the address of the struct Data data; that we already initialized above, like this
pointer = &data;
the lifetime of the pointee restricts the validity lifetime of the pointer, once you go out of the scope where data was declared, then the pointer will point to garbage, because data would have been deallocated.
Another way to make the pointer valid, is using malloc(), i.e. by requestion memory from the system heap, that is done by asking for sizeof(struct Data) bytes, like here1
pointer = malloc(sizeof(struct Data));
after that, you first check that memory was allocated, when there is a problem malloc() is guaranteed to return a special poitner NULL, it's an invalid poitner that helps you check if poitner is actually pointing to valid memory,
if (pointer != NULL)
{
pointer->quantity = 1;
pointer->value = 3.0;
strcpy(pointer->name, "My Name Is ...");
}
In this case the pointer is valid until you decide it isn't, when you do, you must call free() like this
free(pointer);
after that if you try to access the pointer again, undefined behavior will occur.
1You can also make it independent of the type of pointer by using this syntax pointer = malloc(sizeof(*pointer));, since sizeof(*pointer) is equal to sizeof(struct Data).
how are they allocated in memory?
In both cases, it depends on where the variable is defined.
At namespace scope (C++) or file scope (C), it's a global variable, with an address assigned when the program starts. Typically, that's specified by the symbol table, as you say.
At block scope, it's an automatic variable, and memory is typically allocated on the function's stack frame, some time before the program reaches the definition.
At class scope, it's part of the class that contains it.
In the second case I'm assuming the memory address gets stored in a variable of size 32 bits
It's however large a pointer is. On a 32-bit platform, that will be 32 bits. In this case, there is no file_operations object, only a pointer.
Both statements do two things: (1) Define a struct called struct file_operations, (2) Declare an uninitialized variable of that type.
The first allocates space the size of the struct on the stack (or in static storage, if outside a function.) Data members of the structure can then be accessed like a.member1 = 1. When inside a function, a is on the stack. It is just like any other variable declaration, for example int a. If outside a function, it declares a global variable. Its member address can be found using &a. The compiler uses a symbol table while compiling that indicates the type, relative address, etc of each token.
When declaring a global variable and compiling into a library, it also generates a symbol in the binary's symbol table so that it can be linked by the linker.
The second case declares a pointer to a struct file_operations. A pointer is a variable holding a member address, so it has a size of 4 byte in your case. Its type is struct file_operations * which indicates that the data it points to must be of type struct file_operations. The variable here is unintialized. The pointer does not contain a valid address, and dereferencing it would fail. To use it:
struct file_operations a;
struct file_operations* pa = &a;
Would make pa point to a. Then a's members can be access through pa via pa->member1 = 1. The address of the pointer itself &pa is also on the stack (or in static memory when outside a function). &pa is the address of the pointer, aka a pointer to a pointer. pa is the address that the pointer points to.

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.

Why memory is not allocated to class when we create pointer type object?

I am little bit curious about that why memory is not allocated to a class or structure when we create pointer type object ?
For example :-
class A
{
public:
void show()
{
cout<<" show function "<<endl;
}
};
int main()
{
A *a;
a->show();
return 0;
};
Because pointers and memory allocation are a priori completely unrelated. In fact, in modern C++ it’s downright bad to use pointers to point to manually allocated memory directly.
In most cases, pointers point to existing objects – that’s their purpose: to provide indirection. To reiterate: this is completely unrelated to memory allocation.
If you want to directly have an object you don’t need a pointer: just declare the object as-is (= by value):
A a;
a.show();
This code:
A *a;
a->show();
just declares a pointer of type A*. Pointer alone is nothing but a variable that holds an address of some memory in it, i.e. it just points somewhere, nothing else. Pointer of type A* means that it points to memory, where an instance of type A is expected to be found.
a->show(); then just relies on this "expectation", but in fact it just uses uninitialized pointer, which results in undefined behavior.
This could be either solved by dynamically creating an instance of A:
A *a = new A();
a->show();
(which however gives you unpleasant responsibility for cleaning up this memory by calling delete a;) or even better: using an object with automatic storage duration instead:
A a;
a.show();
In the second case, an instance of type A is created automatically and its lifetime is tied to the scope, in which it has been created. Once the execution leaves this scope, a is destructed and memory is freed. All of that is taken care of, without you worrying about it at all.
Allocating a pointer does not equate to allocating an object. You need to use new and instantiate an object on the heap, or create the object on the stack:
A* a = new A();
// Or
A a;
A* aPntr = &a;
Pointer is not an object, it’s just a link that points somewhere. The reason to use them is that you can dynamically change what they’re pointing to.
A a;
A b;
A *pA;
{
bool condition;
// set condition here according to user input, a file or anything else...
if(condition)
pA = &a;
else
pA = &b;
}
Now I don’t have to take care about condition, it even doesn’t have to exist anymore and still I can profit from the choice made above.
pA->show();
Or I can use pointer to iterate over an array:
A array[10];
for(A* pA = array; pA < array+10; pA++)
{
pA->show();
}
(Note I used the original declaration of class A in both examples altough more meaningful it would be if each object of class A contained its specific information.)
There may not be one single reason for A *a; not to allocate an instance of A. It would be at odds with how C++ is designed. I would be somewhat surprised if Stroustrup considered it for long enough to identify a definitive reason not to do it.
A few different ways to look at it:
You didn't ask for an object of type A, so you don't get one. That's how C and C++ work.
A pointer object is an object that holds an address. You may as well ask why stationary manufacturers don't build a house when they manufacture an envelope, as ask why C++ doesn't allocate an object to be pointed at when you define a pointer.
There are many ways to allocate memory. Supposing that memory was going to be allocated, which one would you like? You could argue that in C++ new would be a sensible default for class types, but then it would probably be quite confusing either if char *c; called new char (because the behavior would be different from C) or if char *c; didn't allocate memory at all (because the behavior would be different from char *A;.
How and when would the memory be freed? If it's allocated with new then someone is going to have to call delete. It's much easier to keep things straight if each delete corresponds to a new, rather than each delete corresponding either to new or to defining a pointer with implicit memory allocation.
A pointer can be the location of an object, but it isn't always (sometimes it's null, sometimes it's off-the-end of an array). The object can be dynamically allocated but doesn't have to be. It would be very unhelpful of the language to make a pointer point to an object in cases where you don't need it. Therefore the language gives you the option not to allocate memory when defining a pointer. If you don't want that, then you should initialize the pointer with the result of a call to the memory-allocation mechanism of your choice.
You just create a pointer *a, but not allocate memory for it.
you should use A *a = new A();

C++ deleting a pointer itself instead of deleting the pointed-to-data

I know from reading parashift.com that using delete on a pointer frees the memory
[16.1] Does delete p delete the pointer p, or the pointed-to-data *p?
The pointed-to-data.
The keyword should really be delete_the_thing_pointed_to_by. The same
abuse of English occurs when freeing the memory pointed to by a
pointer in C: free(p) really means free_the_stuff_pointed_to_by(p).
And the wiki article on "delete (C++)" says "many programmers set the pointer to NULL afterwards to minimize programming errors"
Is it necessary to think about deleting the pointer itself?
Is it correct to say that a declared pointer still takes up memory?
i.e. if I were to declare billions of different pointers to NULL, it would still use up memory (and hence I would have a need to delete the pointer itself).
How would I delete the pointer?
Usually the pointer will stop existing at the end of the scope.
Example:
{
int *p = NULL;
// do something with p
} // <-- p will be destroyed here
Hereby the pointer variable is said to have automatic storage duration. If done consistently, assigning 0, or NULL, or nullptr to a pointer variable that doesn't point to an object of the specified type has the advantage that one can easily recognize whether or not it's safe to dereference the pointer. This practice has no direct connection to the lifetime of the pointer or the previously pointed to object (if any).
In contrast, when you have the following code:
{
int *p = new int;
// do something with p
//delete p; // <-- the object p points to will not be destroyed unless it's deleted
} // <-- p will be destroyed here
Again, the pointer variable itself will be destroyed at the end of the scope, because it has automatic storage duration.
In contrast, the int object, which we have allocated using the new operator, to which the pointer points in this example, has dynamic storage duration. It will continue to reside in memory until delete is called to free it. This may result in a memory leak (if you lose any reference to the object p pointed to, as in this example).
Of course, if the pointer is dynamically created by itself, e.g., as in
{
int** p = new int*;
// do something with p
//delete p; // <-- the object p points to will not be destroyed unless it's deleted
} // <-- p will be destroyed here
... this could be the starting point for a recursive example.
Note that there is a thing called static storage duration, which means the variable will exist until the end of the program (e.g., global or static variables). If you want to read up more on this topic see:
http://en.cppreference.com/w/cpp/language/storage_duration
http://en.cppreference.com/w/cpp/language/static
Note that independent of its storage duration, any variable (including pointers) takes up some amount of memory. Generally, if you allocate space for too many objects at the same time you will run out of memory. Therefore, you should avoid implementing things like infinite recursion, fork bombs, memory leaks, or alike.
Is it necessary to think about deleting the pointer itself?
It is only necessary if the pointer itself has no automatic memory management. That is, if storage for the pointer itself was allocated with new or malloc.
Is it correct to say that a declared pointer still takes up memory?
A pointer takes up memory, it has to be stored somewhere in order to be used, right?
if I were to declare billions of different pointers to NULL, it would still use up memory (and hence I would have a need to delete the pointer itself).
Of course it would use up memory, billions * sizeof(void*). Needing to delete the pointer has nothing to do with it taking space or not, everything takes space (well, almost, there are some special optimizations); you only need to delete what was allocated with new.
How would I delete the pointer?
How was it allocated? If it has automatic storage then its memory will be automatically freed when the pointer goes out of scope. If it was allocated with new it has to be deleted with delete, same for new[]/delete[] and malloc/free.
1) Usually a pointer is on the stack or a member of another class and you wouldn't need to worry about deleting such pointer.
2) Yes.
3) Yes, they would use up memory and you would need to release the pointer.
4) Either let a local pointer fall out of scope, or get rid of whichever object contains it.
Finally note that raw pointers are quite out of favor. Prefer either an appropriate container such as vector, or as needed an appropriate smart pointer.
A declared pointer takes up memory on the stack and will be deleted when it goes out of scope. This is the same process that takes place with primitive types. You do not need to worry about memory management for anything on the stack.
The new operator on the other hand allocates memory on the heap, and must be explicitly deleted with delete.
Is it necessary to think about deleting the pointer itself?
it depends on how the pointer was created. if you create a pointer on the stack:
void func(void) {
int* p;
...
}
you should delete the memory pointed to by p (when it makes sense), but p is simply an auto variable which will be "deleted" when the stack is unwind;
Is it correct to say that a declared pointer still takes up memory?
i.e. if I were to declare billions of different pointers to NULL, it would still use up memory (and hence I would have a need to delete the pointer itself).
of course it does... a pointer is just a location in memory containing an address into the virtual memory; in fact doubling the virtual memory space will double the space your pointers occupy (but not necessarily the space occupied by the data they point to).
How would I delete the pointer?
as I said, it depends on how you created the pointer. if you for some reason allocated it on the heap, then you should free that memory as well.
A pointer is simply a variable, like an int. On a 32-bit CPU a pointer will consume 4 bytes of storage, 8 bytes on a 64-bit system.
So if you declare a billion pointers to NULL, you have essentially declared a billion *int*s.
The thing that makes it a pointer is only the fact that the value stored in that variable just happens to be the address of some place in memory. When you call delete on a pointer, you are freeing the memory at that address stored in the pointer, not the memory used by the pointer variable itself.
You can not delete the pointer itself - only pointed by it data.
Pointer is destroyed when its scope is ended:
{
int *p = NULL;
}
After closing bracket the pointer is distroyed.
The question is what is deleting a pointer. If you assign new pointer to the same variable you don't need to worry about deleting billions. If you allocate space for pointer, you surely should delete them, but then again it will be pointer to pointers, so it's pointers, not pointer that is getting deleted. If you allocate space statically (like declaring array of billions of pointers) you can't really delete it.
In short, I think you need a better understanding of the nature of pointer.