I have tried the c++ code
double* p;
*p = 123.0;
in vs 2010, and it broke off because the pointer hasn't been initialized. But I remember I have read in a blog(forget which one...), that the 123.0 is a const value,so p is pointing to a const value now, you can use *p to get 123.0 but you cannot change the value. Which one is the truth?? Thank you!
p doesn't point anywhere and you tell it to store value 123.0. Where should it go? This is undefined behaviour.
If you want it to point to a constant value in a memory address that will stick around, try
static const double d = 123.0;
const double* p = &d;
I can't suggest anything more without context of what you are trying to do.
Your approach is wrong since double* p; only declares a pointer, but it is uninitialized so when you do *p = 123.0; it triggers an undefined behaviour.
You need to point p to a valid double location so you can modify it.
Neil's answer is partially correct. In his example, you cannot change *p anymore like you do in your question. You need to get rid of the const. In that answer, p points to memory on the stack.
If you want to create a heap-allocated double, you would use the new keyword.
double* d = new double;
*d = 123.0;
However, you have to make sure to delete this memory after you are done using it.
delete d;
Since you are using MSVC 2010, which includes some C++11 features, the better way to do the same would be to use unique_ptr. It acts the same as a raw pointer, but it will manage the memory allocated by the pointer ... i.e. it will automatically call delete once it goes out of scope.
unique_ptr<double> d = unique_ptr<double>(new double);
*d = 123.0;
// when d goes out of scope, the memory will be deleted as well
Related
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.
I have noticed that if i create a pointer in a function, it won't let me set a value to it.
for example:
int func() {
int* pointer;
*pointer = 0 //error I get: "Exception: STATUS_ACCESS_VIOLATION"
return *pointer;
}
I get that not letting you set a pointer in the function because if I use a normal int it works:
int func() {
int notAPointer;
notAPointer = 0;
return notAPointer;
}
Can anyone explain to me why that is?
You haven't assigned any memory for your pointer to point to.
That means that dereferencing the pointer (*pointer) causes undefined behavior (like a crash in your case). You need to initialize the pointer before dereferencing it:
int* pointer = new int;
(And afterwards, delete pointer; to not leak the memory. Always delete everything you get from new.)
Also, pointers don't have to point to dynamically allocated data (acquired by a call to new), you can point to automatic (stack) variables too:
int func() {
int valueOnStack = 42;
int* pointer = &valueOnStack;
*pointer = 0;
return *pointer;
}
Because when you declare pointer it is pointing to a completely arbitrary memory location. You can't just write to any old piece of memory.
You need to allocate memory for it first:
int* pointer = new int;
*pointer = 0;
Or just:
int* pointer = new int();
The pointer pointer is uninitialized and points to a random location in memory when you declare it. It could be pointing into the system stack, or the global variables, or into the program's code space, or into the operating system. When you say *pointer = 0;, the program will simply try to write a 0 to whatever random location pointer points to.
The program may explode immediately, or may wait half an hour and then explode, or it may subtly corrupt data in another part of your program and you may never realize it. This can make this error very hard to track down. Make sure you initialize all pointers to a valid address before dereferencing them.
pointer does not point to anything following int* pointer;
So the behaviour of dereferencing it is undefined.
If you'd written
int n;
pointer = &n;
then you could dereference it.
Altenatively, you can allocate memory to it from the heap:
pointer = new int;
But you must remember to call delete pointer; else you'll leak memory.
This code is completely valid inside a function:
int *pointer = 0;
BUT, it would be the same as setting a pointer to the NULL macro.
If you try to set another value the compiler is going to complain that there is no valid conversion from int to int*:
int *pointer = 1; // Error
However, if you want to assign a value to the pointer, follow TartanLlama's answer using new and delete. Allocate memory first and then assign a value:
int *pointer = new int;
*pointer = 1; // OK
// delete when appropriate
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.
Can someone help me with this question?
The memory allocated on line (*) below is not deleted.
void f() {
int z = *new int; // (*)
//...
}
Without changing the code on line (*), is there any way to avoid leaking memory? If so, how? If not, why not?
What I don't understand is, what does *new int mean? Specifically, what does adding the * beside new mean?
Also, what if instead of int z, we have int &z?
That line is the memory leak. It also makes no sense what so ever allocating an int int on heap and derefencing it (with *) before saving it's handle (address returned by new). So the only posible way to avoid the leak is:
return;
// your silly * line here
Without changing the code on line (*), is there any way to avoid leaking memory?
In real life, you would absolutely change that line - it's insane.
Assuming this is an intellectual exercise, then possibilities are:
Add return; before it, so the new never happens;
Override ::operator new to return a pointer that you can access by other means, such as a global variable.
What I don't understand is, what does *new int mean?
new int dynamically allocates an object of type int, and gives a pointer to that. * dereferences that pointer so that the object can be copied to initialise z. The pointer is not stored anywhere, so there is no way to access or delete the dynamic object afterwards.
Also, the initialisation of z from the value of an uninitialised object gives undefined behaviour.
Also, what if instead of int z, we have int &z?
z would be a reference to, rather than a copy of, the dynamic object. It would then be possible to fix the leak with delete &z. That would be an unidiomatic, confusing thing to do; don't do it in real code.
In general, avoid dynamic allocation and, when it is necessary, manage dynamic resources with RAII types, like containers and smart pointers. Raw pointers are error-prone, expecially when exceptions are thrown; anything else is a recipe for insanity.
That to understand this statement
int z = *new int; // (*)
it will be useful to split it logically.
At first there is called operator
new int
Take into account that the memory allocated by this call will not be initialized.
The result of the execution of the statement is some temporary pointer to int that is int *
Let;s name it as p.
In the next step this temporary pointer is dereferenced
*p
and this expression returns some garbage that the allocated memory has.
And this garbage are assigned to variable z.
So the code has no any sense.
At least it would be better to write something as
int z = *new int( 10 );
or
int z = *new int();
or
int z = *new int {};
that to initialize variavle z
Nevertheless in any case there will be memory leak.
The only method that I see to escape the memory leak is to write
int z = *std::unique_ptr<int>( new int() );
No, there's no way to not leak memory with that code, since the pointer returned by new is lost.
*new int means "allocate memory for an int, resulting in a pointer to that memory, then dereference the pointer, yielding the (uninitialized) int itself". I think this is undefined behavior.
I looking for a clarification regarding the pointers. I have compiled the following code in bordland c++ 5.5.1 without any errors. But while i am trying to execute gives a core error.
int main ()
{
int x=10,y=20;
int &a=x;
int &b=y;
int *c;
int *d;
*c=x;
*d=y;
return 0;
}
Basically I am trying to create two reference variable (a,b) and assigned with two variables (x,y). after that I created two pointer variable(c,d) and tried to assign same variables (x,y). This gives me error while exection and not at compilation.
whether I am doing any wrong, this is not a standard assignments of pointer variable. why the pointer assignment is getting failed at this point. Please help me to understand this.
1st Update:
Thanks to all. First, I understood that I am working on a C++ feature (reference variable).
Second, I need to allocate memory for the pointer variables before play with it.
The code you posted is C++, not C. And your problem is that you need to make those pointers actually point at something:
int * c = & x; // make c point at x
* c = 42; // changes x
You have declared c and d as int pointers and you are trying to update their pointed values, they aren't pointing to anywhere valid since you never initialize them with valid memory.
Try c = &x; and then play with c.
You are dereferencing an invalid pointer. 'c' and 'd' were not assigned a memory location and so will be using whatever was previously in memory as their location. You need to do:
int *c = new int;
int *d = new int;
It looks to me like you're not entirely clear on the syntax.
Typing int *c is tricky, because it looks like you're declaring an integer with the name *c. However, this is not the case. This will declare a pointer to an integer, and in C/C++, pointers to a certain type are denoted by appending a * after the type name. Thus, you're declaring a variable of type int* (pointer to an integer), with the name c, even though the spacing makes it look different. For the record, typing int* c yields the same result, and is arguably more readable.
It follows then that typing *c does not reference your variable, as it is actually called c. Instead, what this does is dereference the pointer: it returns whatever object the pointer is pointing to. Or, if the pointer is invalid, cause an error.
If you want to declare a pointer and set it to point to an object at a later point, you need to do this:
int *c;
// stuff goes here
c = &x;
&x will return x's address in memory, which can be assigned to a pointer as a value. Then, you can manipulate the value through the pointer by dereferencing it: e.g. *c = 15.
You have defined two pointer variables c and d but you have not allocated any memory for them. You need to assign some memory to both of them.
Do this:
int *c = &x;
int *d = &y;