This is a newbie C++ pointer question. I have no clue on why this happen...
I found that if i write this code. It is totally valid.
Code1
int *j; //create an pointer j
*j = 50; //assign 50 to the *j, meaning value pointed by address 50 is xxx
However, when I wanna try to make it more simple. The compiler give me this error message.
Code2
开发者_StackOverflowint *j = 50; //i guess this should be the same with Code1...
Compile error
error: invalid conversion from ‘int*’ to ‘int’
So why would be like that?
There's a bit of ambiguity in the C syntax there.
int *j = 50;
is equivalent to
int *j;
j = 50;
Actually, what you're doing in the first snippet of code is dangerous because you haven't allocated any memory for j before assigning a value to it yet. You'll need to make memory for it like so:
in C:
int *j = (int*) malloc(sizeof(int));
*j = 50;
in C++
int *j = new int;
*j = 50;
Or point the pointer at some other block of memory that's already valid:
int k;
int *j = &k;
*j = 50;
printf("%d", k); // 50
Edit: It's worth pointing out that the ambiguity has to do with the '*' symbol. In the declaration, int *j;
the *j means "a pointer named j". But when you're using it in the second line "*j = 50", * becomes the dereference symbol that means "the value at address j".
They have different meanings altogether.
The first one declares a pointer, and sets the int
pointed to by the address currently in j
to 50
. Without other context, this is already bad; the address in j
is not initialized and you'd most likely cause a segmentation fault by writing a value to a random place in memory.
The second piece of code declares a pointer, and defines the address stored in it to 50. If you separate it, it's exactly like writing (note the lack of an asterisk in the second statement):
int *j; j = 50;
After you declare int *j;
a space of type int *
is allocated on the stack (in this case) which has some address addr_stk
and with contents which we do not know, ie. garbage.
+--------+ +--------+
| ??? |----+ | xxx | trying to store 50 here
+--------+ | +--------+
| j | | | |
+--------+ | +--------+
|addr_stk| +---->| ??? | have no permission to access this location
+--------+ +--------+
When you use *j = 50;
the contents of the pointer variable (object) j
is used as the address to store the value 50
in there. Therefore you do an attempt to store the value 50 in some address location which has a garbage address value, which means it could be anywhere. Whenever you will try to access the memory locations which are not allocated to you will not be able to store or access the location, the operating system will stop you from it and throw some error.
What you need to do is first initialize the pointer variable j
with some address which is valid. This can be done by first allocating some memory with malloc
and then using it. Or initializing the j
with the address of some other variable (local or global). like
int *j, i;
j = &i;
*j = 50;
or
int *j;
j = malloc (sizeof (int));
*j = 50;
in both the case when accessing *j
we have a valid address inside j
, therefore using the contents of j
as address (pointer access), is valid, as *j
resolves to a valid memory access.
Important thing is that when you allocate memory with malloc
you should always free the memory. This is a good habit, or else in large programs it will lead to memory leaks.
Both of your examples are wrong.
The first:
int *j;
*j = 50;
stores 50
to the address j
. However, you never initialized j
, so you are simply storing to an unknown address. Sometimes this will "succeed", sometimes this will make your application crash, and sometimes it will merely corrupt your application state without causing an error; it's never what you actually want to do.
The second:
int *j = 50;
tries to initialized a variable of type "pointer-to-int" with a value of type "int", which is an error.
Instead, you want to do something like:
int i = 50;
int *j = &i; // j is now a pointer to i.
or:
int i;
int *j;
j = &i; // note: no * before j. j now contains a valid address.
*j = 50; // store 50 to the address j. After this, i == 50.
The *
is a part of the variable's type, not its name.
int* j
means "I have a variable named j
, which is a pointer to an int".
int* j = 50
(code 2) means "I have a variable named j
, which is a pointer to an int, and which shall be initialized with a value of 50
". This is not allowed; pointers may not be initialized with an integer value other than 0
without an explicit cast. Explicitly casting to get around this is a very, very bad idea if you don't know what you are doing, and if you are asking these questions then it is absolutely certain that you don't know what you're doing well enough to try.
You're supposed to be able to figure this out from the error message. An invalid conversion is just that: your code tries to convert from one type to the other (via the assignment), and that is not valid. The thing you're assigning to is not of a compatible type for what you're assigning. It tells you what the types involved are, too.
*j = 50
(second line in code 1) means "write the value 50
at the location that j
points at". This is bad, because j
hasn't been initialized yet. This is called "undefined behaviour" and is exactly that - it may fail in any number of ways, or not, but it is always wrong even if it seems to be working. But it will compile, and most compilers will not even try to warn you about this sort of thing unless you ask them for really high warning levels - if at all.
int *j = 50
Is actually equal to
int *j;
j = 50;
Because assigment on initialization assigns the variable itsel no matter what.
In both cases it's a very bad idea because the pointer is invalid.
精彩评论