2013-04-28 2 views
0

Я немного запутался, почему следующие аварии коды:Почему эти указатели вызывают сбои?

int main(){ 
    int *a; 
    int *b; 

    *a = -2; 
    *b = 5; //This line causes a crash on my system. 

    return 0; 
} 

В случае, если не память автоматически выделяются два указателя и два целых числа, прежде чем время выполнения из-за заявления?

Или вы всегда должны явно выделять память?

+6

«Не следует автоматически выделять память» - Откуда у вас такая идея? Это, конечно, неверно. Сколько памяти должно быть выделено указателю *, который может указывать на произвольно длинный массив 'int'? –

+0

@ Code-Guru: я бы подчеркнул * раньше *, а не _must_. ;-) –

+0

@PieterGeerkens Хорошая точка (er) –

ответ

3

Нет. Вы указали только указатели, а не то, на что указывают. Указатели выделяются в стеке, и поскольку вы не инициализировали их ни к чему, их значения - мусор.

int main() { 
    int a = 7; 
    int *p_a; // p_a contains whatever garbage was on the stack at its 
       // location when main() is called. (Effectively points nowhere). 

    p_a = &a; // p_a points to (gets the address of) variable a, also on 
       // the stack. 

    printf("Before: a = %d\n", a); // prints 7 

    *p_a = -2;  

    printf("After: a = %d\n", a); // prints -2 

    return 0; 
} 

Я бы поставил код вышеприведенного примера и выполнил его в отладчике. Вы увидите, что я имею в виду, на что указывает p_a.


не должна память автоматически выделяется два указателя и два целых числа, прежде чем время выполнения из-за заявления?

Я только вижу, что вы указали два указателя. Где два целых числа?

Или вы всегда должны явно выделять память?

Указатели должны указывать на что-то. Либо локальные переменные в стеке, либо malloc 'd память из кучи.

+0

Не int * объявляет указатель, который указывает на целое число? – Josh

+1

Да, но какое целое оно указывает? –

+1

@Josh Рассматривайте фразу «ее собака». Это ссылка на чью-то «собаку», но она не сделает, чтобы сказать «дайте собаке кость», если вы не сказали мне, кто она. Точно так же «указатель на int» не сообщает системе, которая есть int. –

0

Вы только что указали указатели, но вы их не инициализировали. Таким образом, вы не можете быть уверены, что *b = 5 приводит к сбою программы. Это может быть *a = -2. Чтобы исправить это, вы также должны инициализировать свои указатели.

int aval = -2; 
int bval = 5; 

int *a = &aval; // declared and initialized pointers 
int *b = &bval; 

// Now you can change the value using the pointer 
*a = 15; 
*b = 20; 
0

Ваши * а и * b указатели неправильно инициализированы. Попробуйте это:

int my_a; 
int my_b; 

int *a; 
int *b; 

a = &my_a; // init the pointer a to the direction of my_a int variable 
b = &my_b; 

*a = 3; // set the my_a value via pointer 
*b = 2; 
1

В этом коде:

int* a; 
*a = -2; 

a неинициализированному указатель разыменования, который производит неопределенное поведение, что вы, к счастью, удалось наблюдать, как аварии вашей заявки.

Вы должны инициализировать указатель (чтобы она указывала на действительную память) перед вами разыменованием его (то есть, прежде чем использовать *, оператора разыменования):

int a; 
int* pA = &a; 
*pA = -2; 
1

Рассмотрим

int m; 
int n; 
m = n; 

Это недопустимо, потому что вы пытаетесь использовать n, но вы не присвоили ему значение.Сейчас:

int *a; 
*a = -2; 

Кроме того, это является недопустимым, потому что вы пытаетесь использовать a, но вы не присвоили ему значение. Значение a не является int, это указатель на int. Например,

int someint; 
a = &someint; 
*a = -2; 

ставит -2 в someint. Без назначения на a место, куда нужно поставить -2, не подлежит определению. Кроме того,

a = malloc(sizeof(int)); 
*a = -2; 

Здесь a присваивается значение адреса какого-либо места в куче; -2 переходит в это место кучи.

Возможно, аналогия была бы полезна:

Рассмотрим фразу «ее собака». Это ссылка на чью-то «собаку», но она не сделает, чтобы сказать «дайте собаке кость», если вы не сказали мне, кто она. Точно так же «указатель на int» не сообщает системе, которая есть int.

Смежные вопросы