Some basic pointer questions - c++

I have a few silly questions (probably for most), it's less about 'how' do I do them and more about 'why' do they work this way? I know you are not supposed to ask multiple questions, but these are fairly small and related to one topic. Seems like it'd be a waste to separate them out.
I understand for the most part pointers, and the operators themselves. (Although I am curious why the * is called the de-reference operator, since isn't it referring to a reference of what it contains?)
I.e:
int x = 25;
int *p = &x;
So & makes sense, since *p is a place in the stack of type int that contains the address of x (which we know is 25).
So by saying *p are we 'referencing' the address of p which is pointing to the 25. Maybe it's just an English semantics thing? Maybe someone can explain why it's called 'de-reference'?
Take this valid code sample:
int *p = new int;
*p = 5
Simple enough, we're making a new place in the stack with the size of an int pointer (whatever that may be). p will contain some address that has a 5 for a value.
Thing is, I haven't actually declared anything that's storing a 5, so what the heck is p pointing to? I mean, this does indeed work, but I never made a int x = 5 or anything like that, and gave the address to p to point to? How does it even know?
p contains an address that points to something, but I never made that 'address' it's pointing to? Does the compiler just know to create another address somewhere else? (Sorry if this is a really stupid question.)
I was reading on here about some memory leaks on another question:
A *object1 = new A();
pretending A is a class first of all. Someone was saying the object1 stores the value of A. Isn't that incorrect? Doesn't object1 store the address of what new A() created and is pointing to it?
Because delete object1 deletes the pointer, which points to the new A() (but from the other question delete object1 would indeed be the correct syntax. So does that leave the new A() hanging out there? Or does it get automatically deleted? (As you can tell I'm a bit confused.)
If delete object1 does indeed delete what the pointer is pointing to and not the pointer itself, doesn't this just leave a dangling pointer?

Here
int x = 25;
int *p = &x;
* is not the dereferencing operator. It's part of the type of p. It basically says that p is a pointer.
Here
int *p = new int;
*p = 5;
The key is new int. It dynamically creates an int and returns it's address, so p now points to that address. *p = 5 (btw, here * is the dereferencing operator) modifies the value -- of that dymanically allocated int -- to 5
Indeed object1 holds the address of the newly created A. Since we're here we should clarify this: A is a (user defined) type. So it makes no sense to say that A has a value. Objects of type A have value.
delete p doesn't delete a pointer. It does 2 things:
Destroys an object created by a new-expression
Deallocates storage previously allocated by a matching operator new
The pointer isn't actually changed, i.e. it still points to the same address. Only now that address isn't allocated, i.e. can't be dereferenced anymore.
You can further refer to this SO answer - Static, automatic and dynamic storage duration to further understand objects, pointers, new/delete.

1: I'm not sure what you're implying when you say "which we know is 25". The address of x is not 25, rather that is the value of x. You do not set the address of x in a statment like int x = 25
But to answer your question, p is a reference, which is to say its value is an address. Accessing the value stored at the address p requires the *p, which dereferences the pointer.
2: You have allocated memory for p; you executed a new. You have allocated 4 (or 8) bytes of memory for a new integer on the heap, so p is pointing to a newly allocated block of memory. Saying *p = 5; tells the compiler to set the value stored at that address to 5.
3: Your assumption is correct; object1 does not store the value of a new A, rather points to a block of memory equivalent in size to aninstance of an object of size A.
delete object1; Does not delete the pointer. The pointer is simply an integer on the stack, rather it gives back the allocated memory for that pointer back to the system. A as you knew it is deleted, but the pointer still exists, and using it at this point is undefined behavior. You are correct in assuming you have a dangling pointer now, that is why you should always set deleted pointers to NULL.

Related

C++ raw pointers and "delete"

I have a question regarding the code snippet below:
double d = 20.1;
double* pd = new double;
...
pd = &d;
delete pd;
The last line throws an error in Visual C++ 2015. Does this mean that the pointer "pd" points to the stack address of "d" and its original pointed-to address in the heap (right-hand side of the equal sign in the second line) has leaked?
Yes, you leaked the double originally pointer by pd, but that's not what's causing the error.
The error is a result of you trying to delete a stack allocated address. That is is strictly undefined behavior. delete will only work for pointers which were created with new.
Variables hold values. Pointer values are just that, values. Not names. Not variables.
When you manipulate a pointer value, for example to pass it to delete, you only care about the value.
It's essentially equivalent to:
int one=1;
one=2;
std::cout << one; // you won't be surprised to see 2, will you?
The value currently in the variable matters; not some previous value. Not the name.
Your program tries to deallocate (delete) an object that wasn't allocated by you (the user), but by the compiler.
Does this mean that the pointer "pd" points to the stack address of "d" and its original pointed-to address in the heap (right-hand side of the equal sign in the second line) has leaked?
Yes, that is exactly what this means.

C++ delete effect on pointer variables

I have the following question.
If
int a = 5;
and
int *b = new int(a);
and then I do
delete b;
it will delete the object that b is pointing to if I am not mistaken. What I don't understand is what happens to b?
Does b remain a pointer pointing to the address where the object created by new used to live?
then I do delete b; it will delete the object a that b is pointing to
It will delete the object that b is pointing to yes, but that object has nothing to do with the object a (other than they both have the same value).
What I dont understand is what happens to b? Does b remain a pointer pointing to the adress where the object created by new used to live.
That's exactly what happens to b i.e. nothing happens to it. delete only affects the dynamic memory management and pointed object (calling its destructor). The pointer variables value itself won't be changed, but is a dangling pointer afterwards.
Yes, b remains a valid pointer - it's simply the address to which it points that becomes invalid. Declaring
int* b;
will reserve storage for a variable b (albeit unitialized), in just the same way as
int c;
reserves space for storing an integer.
However, your b never pointed to the address of a - this is not what new int(a) does. Your b was a pointer to an address containing a copy of the value of a.
Your understanding is completely wrong. First, delete b; will call the destructor for the type e (a no-op in the case of a primitive type like int) but then it will crash because there will be an attempt to deallocate the object at b, but since this is an object with automatic storage duration the attempt will fail in a major way.
Also, the initialization of b would need to be "int * b = &a;", trying to assign an int to a int * will produce a compile-time error.
When you delete an object by pointer, two things happen:
The memory that has previously been allocated to the object becomes available for re-allocation, and
The pointer becomes invalid (reference: what is dangling pointer?).
Once you call delete b you can reuse b to point to another object, like this
b = new int(123);
or like this
int a(123);
b = &a; // Obviously, you can't delete b after this
or you can set it to nullptr, like this
b = nullptr;
but you cannot dereference the pointer, because it would cause undefined behavior.
Does b remain a pointer pointing to the adress where the object created by new used to live?
Usually, that is exactly what happens - the value of b remains unchanged. However, there is no standard-compliant way to find out, because C++ implementation is free to set it in whichever way it likes. For example, the pointer could be set to a trap representation, so merely printing the value of the pointer would cause a crash.
You can't delete memory that is not allocated by new.
You can't apply deleteat any pointer you didn't initialize with new.
delete b would exhibit undefined behavior, as the value of b was not obtained with new expression.
Thanks,
Raghava

C++ Pointer and Memory Allocation

I am teaching myself C++. It is my first programming language and I am struggling with the wording associated with the memory allocation of pointers.
Consider this statement:
int *p;
int x;
p = &x;
*p = 8;
Value
&p 1400
p 1800
*p 8
x 8
&p is the memory address of p.
p is the memory address pointed to by the pointer p.
*p is the value of the memory address pointed to by the pointer p.
I understand this. However the book states:
p = &x stores the address of x in p. However, no new memory is allocated.
This is confusing. Memory has been allocated, else p would be undefined.
Now consider this statement:
int *p;
p = new int;
*p = 28;
Here, you dont need an additional variable to make *p valid and meaningful, because memory has been allocated.
So, I guess my question is:
What is the author's meaning of his statement, "Memory is not allocated.", when considering the code block?
p = &x stores the address of x in p. However, no new memory is allocated.
100% true. All of the allocation was done in the preceding two lines.
int *p; // allocation of p here
int x; //allocation of x here
p = &x; // no allocation here.
p = &x; is just an assignment of the location of previously allocated memory to a previously allocated pointer. Whether storage is allocated on the stack, the heap, or whatever the current system uses instead of a stack or heap is irrelevant.
For the second example,
int *p; //allocation of p here
p = new int; // allocation of one nameless int AND assignment of that int to p here
*p = 28; // no allocation
Generally the single word 'allocated' is used as an abbreviation for 'allocated out of heap storage using the 'new' keyword, a library routine such as 'malloc', or some other such mechanism (directly or indirectly)'.
Here the statement 'p = &x;' means that the value of p is set to the storage address of x, which is allocated on the stack. Since the stack storage is managed automatically rather than at the programmer's discretion, we choose not to refer to this as 'allocated' in colloquial usage.
Memory is allocated on the stack when you first declare the variable. Here, memory is allocated in
int *p;
int x;
So, p = &x; stores the memory address of x in the previously allocated memory for p on the stack.
"p = &x stores the address of x in p. However, no new memory is allocated."
I think this probably just means that in this particular statement p takes the address of x and no new memory is allocated for x. The memory for x was probably earlier allocated but initialization of p doesn't allocate new memory for x.
But in the latter statement
int *p;
p = new int;
*p = 28;
p points to a new chunk of memory that has been allocated because it is initialized with "new int".
"p = &x stores the address of x in p. However, no new memory is allocated." Because 'x' was created on the stack, not on the heap (just like the variable 'p', and all other 'local variables'). It seems your 2nd example is incorrect, but I'm not 100% sure.
Author probably refers to heap allocation. Both p and x are allocated on stack, which is really just incrementing (or decrementing, depending on machine type) the stack pointer. They're deallocated when they go out of scope. OTOH, new int allocates it from heap memory, which probably takes more time to do, but can live longer than it's scope: you manually deallocate it using delete. Either case, pointer works well: this might be non-evident at first, but you can take the address of a variable on the stack or one that's allocated from the heap using the same type.
Well I got that book and the explanation provided by others is correct. Just adding mine too.
When you compile a function, unless it is a variable argument one, the frame size and format is already known to compiler. Now when you call this function, compiler reserves the memory for this frame on the stack above (or below) the caller function. You can see this happening yourself.
void fun(){
int a,b;
printf("addr fun &a=%u, &b=%u",&a,&b);
callfun();
}
void callfun(){ int c;
printf("addr callfun &c=%u",&c);
}
On most architectures, address may seem decreasing - but logically by calling calllfun(), we created a frame above previous frame.
So, one can say that memory for these variables was created transparently and programmer never cared for that. When the stack grows, more memory is used, and freed when the function calls come closer to the main entry point function. But in other case, when you use new operator, programmer explicitly asks for memory in addition to what has been already allocated on the stack. This is fulfilled from another region in program's address space called heap. OS provides facility for doing this.
In your case, author just said that since the function carrying all these variables was already called, memory has already been allocated (on stack) in the process and NO NEW memory was created. However, you may use new operator to allocate more memory if you want.

Program crashes when deleting a pointer pointing to the heap?

If I go...
int *foo = new int;
foo += 1;
delete foo;
Most of the time it crashes. Is there a reason for this? I'm trying to have the pointer point one spot forward (4 bytes). Thanks.
Edit (six months later): This was the first question I asked on SO, and it was a silly question and deserved the downvotes. It can be deleted if it's of no use to learners. I was indeed talking about allocating an int of four bytes on the heap, then moving the pointer four bytes forward, and then deleting the int pointer, essentially deleting God knows what, leading to undefined behaviour. Thanks for your help.
The only thing you can safely pass to delete is something you got when you called new, or nullptr, in that case the delete won't do anything.
You changed the value of the pointer - therefore it isn't "something you got when you called new"
You must pass to delete the value that new returned. You don't do that.
I think that you are confused as to what you are passing to delete. I think that you believe that delete foo will delete the memory associated with the variable. It doesn't. It deletes the memory whose address is stored in foo.
As an example, this is legitimate:
int* foo = new int;
int* bar = foo;
delete bar;
What matters is not the name of the variable, but rather the value of the variable.
Here's another example:
int* arr = new int[10];
int* ptr = arr;
for (int i; i < 10; i++)
{
*ptr = i;
ptr++;
}
delete[] arr;
In order to perform pointer arithmetic, and retain the address returned by new[], we introduced an extra variable. I used an array because it doesn't make sense to perform arithmetic on a pointer to a single value.
Note that in the code above, it could be written more clearly using arr[i] = i and so avoid the need for a second pointer variable. I wrote it as above to illustrate how you might code when pointer arithmetic is the right option.

c++ what is "pointer = new type" as opposed to "pointer = new type []"?

In many tutorials, the first code samples about dynamic memory start along the lines of:
int * pointer;
pointer = new int; // version 1
//OR
pointer = new int [20]; // version 2
They always proceed to explain how the second version works, but totally avoid talking about the first version.
What I want to know is, what does pointer = new int create? What can I do with it? What does it mean? Every tutorial without fail will avoid talking about the first version entirely. All I've found out (through messing about) is this:
#include <iostream>
using namespace std;
int main()
{
int * pointer;
pointer = new int;
pointer[2] = 1932; // pointer [2] exists? and i can assign to it?!
cout << pointer[2] << endl; // ... and access it successfully?!
};
The fact that I can subscript pointer tells me so far that pointer = new int implicitly creates an array. But if so, then what size is it?
If someone could help clear this all up for me, I'd be grateful...
My teacher explained it like this.
Think of cinema. The actual seats are memory allocations and the ticket you get are the pointers.
int * pointer = new int;
This would be a cinema with one seat, and pointer would be the ticket to that seat
pointer = new int [20]
This would be a cinema with 20 seats and pointer would be the ticket to the first seat. pointer[1] would be the ticket to the second seat and pointer[19] would be the ticket to the last seat.
When you do int* pointer = new int; and then access pointer[2] you're letting someone sit in the aisle, meaning undefined behaviour
This is a typical error in C and C++ for beginners. The first sentence, creates a space for holding just an int. The second one creates a space for holding 20 of those ints. In both cases, however, it assigns the address of the beginning of the dynamically-reserved area to the pointer variable.
To add to the confusion, you can access pointers with indices (as you put pointer[2]) even when the memory they're pointing is not valid. In the case of:
int* pointer = new int;
you can access pointer[2], but you'd have an undefined behavior. Note that you have to check that these accesses don't actually occur, and the compiler can do usually little in preventing this type of errors.
This creates only one integer.
pointer = new int; // version 1
This creates 20 integers.
pointer = new int [20] // version 2
The below is invalid, since pointer[2] translates as *(pointer + 2) ; which is not been created/allocated.
int main()
{
int * pointer;
pointer = new int;
pointer[2] = 1932; // pointer [2] exists? and i can assign to it?!
cout << pointer[2] << endl; // ... and access it succesfuly?!
};
Cheers!
new int[20] allocates memory for an integer array of size 20, and returns a pointer to it.
new int simply allocates memory for one integer, and returns a pointer to it. Implicitly, that is the same as new int[1].
You can dereference (i.e. use *p) on both pointers, but you should only use p[i] on the pointer returned by the new int[20].
p[0] will still work on both, but you might mess up and put a wrong index by accident.
Update: Another difference is that you must use delete[] for the array, and delete for the integer.
pointer = new int allocates enough memory on the heap to store one int.
pointer = new int [20] allocates memory to store 20 ints.
Both calls return a pointer to the newly allocated memory.
Note: Do not rely on the allocated memory being initialized, it may contain random values.
pointer = new int; allocates an integer and stores it's address in pointer. pointer[2] is a synonym for pointer + 2. To understand it, read about pointer arithmetic. This line is actually undefined behavior, because you are accessing memory that you did not previously allocate, and it works because you got lucky.
int* p = new int allocates memory for one integer. It does not implictly create an array. The way you are accessing the pointer using p[2] will cause the undefined behavior as you are writing to an invalid memory location. You can create an array only if you use new[] syntax. In such a case you need to release the memory using delete[]. If you have allocated memory using new then it means you are creating a single object and you need to release the memory using delete.
*"The fact that i can subscript pointer tells me so far that I pointer = new int implicitly creates an array. but if so, then what size is it?"
*
This was the part of the question which I liked the most and which you emphasize upon.
As we all know dynamic memory allocation makes use of the space on the Stack which is specific to the given program.
When we take a closer look onto the definition of new operator :-
void* operator new[] (std::size_t size) throw (std::bad_alloc);
This actually represents an array of objects of that particular size and if this is successful, then it automatically Constructs each of the Objects in the array. Thus we are free to use the objects within the bound of the size because it has already been initialized/constructed.
int * pointer = new int;
On the other hand for the above example there's every possibility of an undefined behaviour when any of
*(pointer + k) or *(k + pointer)
are used. Though the particular memory location can be accessed with the use of pointers, there's no guarantee because the particular Object for the same was not created nor constructed.This can be thought of as a space which was not allocated on the Stack for the particular program.
Hope this helps.
It does not create array. It creates a single integer and returns the pointer to that integer. When you write pointer[2] you refer to a memory which you have not allocated. You need to be carefull and not to do this. That memory can be edited from the external program which you, I belive, don't want.
int * pointer; pointer = new int; // version 1
//OR
pointer = new int [20] // version 2
what I want to know is, what does pointer = new int create? what can I do with it? what does it mean? Every tutorial without fail will avoid talking about the first version entirely
The reason the tutorial doesn't rell you what to do with it is that it really is totally useless! It allocates a single int and gives you a pointer to that.
The problem is that if you want an int, why don't you just declare one?
int i;