2013-08-01 4 views
0

Я пытаюсь присвоить значение атрибутам указателя на структуру, но получить ошибки сегментации.Присвоение значения атрибуту struct

typedef struct { 
    int id; 
    char payload[10]; 
    }packet; 

    void main(){ 
    packet *header; 
    header->id = 1; 
    } 

Он компилируется, но это дает мне ошибку seg, когда я запускаю его. Он работает только при использовании «malloc» при создании заголовка. Почему это? Обычно мне не нужно выделять память для других типов указателей.

+2

Помните, что правильный тип возврата для 'main()' is 'int', а не' void', несмотря на то, что вы можете прочитать в многочисленных книгах. Кроме того, ни один из нижеприведенных ответов о том, что использование 'malloc()' фактически мешает проверять, что 'malloc()' преуспел. Конечно, в рамках этой программы сбой крайне маловероятен. Однако хорошая практика остается хорошей практикой, а не проверкой 'malloc()' в конечном итоге укусит вас - возможно, когда ваша программа будет демоверсифицирована генеральному директору или выпущена тысячам, если не миллионам клиентов, с вытекающими из этого затратами на исправление проблема. –

+0

Если вы видите 'void main()' в книге, это знак того, что автор не очень хорошо знает C и что вы должны найти лучшую книгу. ('void main()' или лучше 'void main (void)', может быть верным для встроенной системы, но если вы работаете над такой системой, вы уже должны это знать.) –

ответ

3

В этом случае заголовок не инициализируется - это указатель, поэтому означает, что это не указывает на что-либо значимое. Когда вы пытаетесь присвоить значение header-> id, вы получаете segfault. Это совершенно логично, и правильно работать только тогда, когда у вас есть память malloced.

Либо вы хотите создать фактический пакет:

packet header; 
header.id = 1; 

или вы хотите кучу выделить один:

packet* header = malloc(sizeof(packet)); 
if(header){ //Check if malloc succeeded 
    header->id = 1; 
} 
1

Вы можете сделать одну из двух вещей:

packet *header = (packet*) malloc (sizeof (packet)); 

или

packet header; 
header.id = 10; 

В зависимости от вашего варианта использования, вы можете быть более подходящим, чем другой. Если вы собираетесь использовать malloc, не забудьте позвонить по телефону free.

1

Когда вы говорите: «Обычно мне не нужно выделять память для других типов указателей», либо указатель является примитивным типом (например, int), либо структура уже выделяет некоторую память (возможно, из стека) ,

Так это должно работать без таНоса:

int main() { 
    packet headerOnStack; 
    packet *header = &headerOnStack; 
    header->id = 1; 
} 

Однако, поскольку он находится на стеке, когда main() возвращается, то структура будет. Обычно это не проблема, потому что как только main() вернется, ваша программа будет выполнена. Если бы это была другая функция, тогда это было бы фактором, который вы должны учитывать.

+0

Вообще говоря, один раз «main 'возвращается, все исчезнет ... – Sinkingpoint

+0

Если вы опубликуете предлагаемое исправление, измените неверный' void main() 'на правильный' int main (void) '.(Предположительно, 'void main()' может быть правильным для встроенной системы, но вряд ли OP работает с такой системой.) –

0

Неисправность здесь заключается, что вы не инициализировать указатель, который будет из-за этого, точка ничего, пытаясь получить доступ к атрибуту расположения указателей, которые до сих пор «ничего» не приведет к недостатку SEG

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