2012-03-30 1 views
1

Я потерян. Я не могу назначить int разыменованным int *.Нельзя назначить int для разыменованных int в C

printf("in octave\n"); 

    int *default_octave; 
    printf("attr[%d]: %s\n",i+1,attr[i+1]); 

    const char *octave_char = attr[i+1]; 
    printf("octave_char: %s\n", octave_char); 

    int octave_number = atoi(octave_char); 
    printf("octave_number: %d\n", octave_number); 
    fflush(stdout); 

    *default_octave=octave_number; 
    printf("in octave pt 2\n"); 
    fflush(stdout); 

Это выход:

in octave 
attr[1]: 4 
octave_char: 4 
octave_number: 4 
Segmentation fault 

Почему?

Запуск отладчика GDB добирается до этой линии, а затем и от сбоев.

0   int octave_number = atoi(octave_char); 
(gdb) s 
41   printf("octave_number: %d\n", octave_number); 
(gdb) 
octave_number: 4 
42   fflush(stdout); 
(gdb) 
43   *default_octave=octave_number; 
(gdb) print octave_number 
$1 = 4 
(gdb) s 

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000400a7b in parse_song (song_data=0x7fffffffe7a8, attr=0x602600) at nullaby.c:43 
43   *default_octave=octave_number; 
(gdb) 

Я понятия не имею, что я могу сделать, чтобы исправить это.

ответ

3

У вас есть int pointer. Правильно.

Это просто означает, что у вас есть переменная, указывающая на некоторую область памяти.
Но вы не выделили/не зарезервировали эту область памяти. Поэтому он может указать на что угодно.

И это обязательно укажет на область памяти, которой вы не владеете, следовательно, ошибка сегментации.

Вам нужно выделить память для указателя ...

Например:

int * default_octave = malloc(sizeof(int)); 

Или вы также можете использовать:

int default_octave_val; 
int * default_octave = &default_octave_val; 

Либо выделить память для хранения ИНТ (а затем получить указатель на допустимую область памяти) или создать указатель на существующую область памяти (в данном примере - адрес стека).

Затем вы можете удалить ссылку на этот указатель, поскольку он указывает на действительную область памяти.
Если это не так, вы будете иметь ошибку сегментации или ошибку шины, в зависимости от вашей ОС.

+0

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

+0

Конечно ...:) Но здесь нет предпочтительного способа ... Все зависит от того, что пытается сделать op ...Как указатель может указывать на что угодно, он может указывать на адрес стека или адрес кучи ... Просто нужно указать правильный адрес, если вы хотите разыменовать его ... – Macmade

+0

Нет проблем с подсчетом голосов, до тех пор, пока оп получает ответ, который ему нужен ...:) – Macmade

6

Это segfaults, потому что вы никогда не инициализируете default_octave, чтобы указать на все, что может хранить int.

+0

Например, вы можете назначить адрес другого объекта 'int',' default_octave = & another_octave' или вы можете сами выделить его для памяти, например. 'default_octave = malloc (sizeof (int));' (который впоследствии должен быть освобожден с помощью 'free (default_octave);', и выделение памяти только для одного 'int' не так уж и полезно). – dreamlax

+0

@OliCharlesworth: Я ниспровергнутый, но с тех пор удален. Я вижу, что вы эксперт по C, и что это чрезвычайно важная проблема для вас. Однако я не чувствую, что этот ответ полезен для ОП. Тем не менее, вы правильно определили проблему очень скоро после того, как сделал Джеймс Маклафлин. – bernie

+0

@bernie: достаточно справедливо. Моя политика заключается в написании минимальной должности, которая отвечает на вопрос; если ОП не понимает, они всегда могут комментировать, и я объясню. –

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