Почему следующий код C недопустим? - PullRequest
3 голосов
/ 13 марта 2009

Рассмотрим типичную среду, почему следующий код недопустим в C?

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

Ответы [ 7 ]

31 голосов
/ 13 марта 2009

Вы не можете присвоить что-либо адресу x, потому что он x не является значением lvalue

(lvalue - это «что-то, что может быть назначено», т.е. оно не может быть на L eft стороне знака равенства)

Попробуйте

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

Теперь x указывает на выделенную память, и вы можете делать такие вещи, как

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

Вы можете назначить адрес x на что-то еще, используя оператор & следующим образом:

int x = 1;
int* y = &x;  // y now holds the address of x
*y = 2;       // Now x = 2
11 голосов
/ 13 марта 2009

Потому что адрес x не является lvalue - его нельзя изменить. C позволяет вам изменять то, на что указывают адреса, но не позволяет вам самим изменять адреса.

3 голосов
/ 13 марта 2009

Все правильно. Адрес X во время выполнения вашего кода является ПОСТОЯННЫМ. Другими словами, он говорит: «Эй, вы можете ИЗМЕНИТЬ, где я, компилятор, храню переменную« x »».

Вы могли бы сделать это

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

}
2 голосов
/ 13 марта 2009

Адрес переменной не может быть изменен. Вместо этого вы, скорее всего, хотите что-то вроде этого:

int *x = (int *)malloc(3 * sizeof(int));
...
free(x);
1 голос
/ 13 марта 2009

Не то чтобы это было совершенно ценно, но поскольку никто больше не поднял его (все вышеприведенные ответы верны, кстати, и излишни, я согласен, что люди должны голосовать за правильный ответ, а не повторять одно и то же более).

В вашем примере, x является переменной стека. malloc дает вам кучу памяти. Это, вероятно, не то, о чем вам нужно думать слишком много в сегодняшнем программировании, но если вы когда-нибудь будете работать в среде, где объем памяти выше, вы захотите максимально сэкономить свой стек.

Стоит также отметить, что по какой-то причине вы выделяете 3 * sizeof (int). Даже если вы МОЖЕТЕ выделить память для стека, в вашем примере, поскольку вы пытаетесь получить только 1 int, вам потребуется только 1 * sizeof (int), остальное будет потрачено впустую.

1 голос
/ 13 марта 2009

& x возвращает указатель на x. Вы не можете использовать его в левой части задания, только справа.

Если вы хотите назначить что-то указателю, вы должны объявить это как указатель, как int * x;

0 голосов
/ 13 марта 2009

Так устроен язык. Чтобы делать то, что вы хотите, используйте указатель.

...