views:

481

answers:

7

Consider a typical environment, why is the following code illegal in C?

{
int x;
&x = (int*) malloc(3*sizeof(int));
...
}
+27  A: 

You can't assign something to the address of x because he address of x is not an lvalue

(An lvalue is "something that can be assigned to", i.e. it cannot be on the Left side of an equals sign)

Try

int* x;
x = (int*) malloc(3*sizeof(int)); // TODO: Call free(x)

Now x points to your allocated memory and you can do things like

int foo = *x;
int bar = x[0];

You can assign the address of x to something else, by using the & operator this way:

int x = 1;
int* y = &x;  // y now holds the address of x
*y = 2;       // Now x = 2
Daniel LeCheminant
+2  A: 

The address of a variable cannot be changed. Instead you most likely want something like this:

int *x = (int *)malloc(3 * sizeof(int));
...
free(x);
NilObject
Even if x were on the heap, the code wouldn't work. (E.g. when using global variables.)
strager
Good point, edited to clarify.
NilObject
A: 

That's the way the language is designed. To do what you want, use a pointer.

Mark Ransom
+9  A: 

Becauase the address of x is not an lvalue - it is not something that can be modified. C allows you to change things that addresses point to - it does not allow you to change the addreses themselves.

anon
So addresses aren't l-values, because you can't assign to them?
KingNestor
An lvalue is defined as something you can assign to. So if you can't assign to it, then it's not an lvalue by definition.
Chris Lutz
KingNestor, it's not an lvalue because it doesn't need to be stored somewhere. lvalue means "has a location". historically, lvalue means left-value and is the left side of an assignment - but that's history. examples of lvalues that can't be assigned to are arrays and constants (e.g const int).
Johannes Schaub - litb
on the other side, you can't assign to rvalues. so neils answer is still correct i think. but sadly, there *are* people where all hope is lost, like for this guy: http://stackoverflow.com/questions/502059/passing-pointers-of-arrays-in-c/502072#502072 :)
Johannes Schaub - litb
+1  A: 

&x returns pointer to x. You can't use it in the left part of an assignment, only on the right.

If you want to assign something to a pointer you have to declare it as a pointer, just like int *x;

Andrea Ambu
+3  A: 

Everyone is correct. The address of X at the time your code executes is a CONSTANT. In other words it says "Hey you can CHANGE where I, the compiler, store the 'x' variable."

you could do this

int main()
{
    int* x;
    *(&x) = malloc(3*sizeof(int));

}
Jeff G
+1  A: 

Not that this is entirely valuable, but since no one else brought it up (all the above answers are correct, btw, and redundant, I agree that people should vote the right answer up, rather than saying the same thing over and over).

In your example, x is a stack variable. malloc gives you heap memory. That's probably not anything you need to think about too much in today's programming, but if you ever work in an environment where memory is at a premium, you'll want to save your stack as much as possible.

It's also worth noting that for some reason you're allocating 3*sizeof(int). Even if you COULD allocate memory to the stack, in your example, since you're only trying to get 1 int you'd only need 1* sizeof(int), the rest would be wasted.

Dr.Dredel