2016-06-12 2 views
1

Я создал связанный список со следующим кодом. Как вы можете видеть, я использовал malloc для создания списка размером 3. Но я инициализировал цикл for размером 10 для инициализации и печати.C Размер связанного списка не ограничен malloc

#include <stdio.h> 
#include <malloc.h> 
#include <stdlib.h> 

struct node { 
     int value; 
     struct node *next; 
}; 

int main() { 
     //code 
     struct node **head; 
     struct node *curr; 
     curr = (struct node *) malloc(sizeof(struct node)*3); 
     head = &curr; 
     printf("done 1\n"); 
     (*head)->value = 0; 
     (*head)->next = NULL; 
     for(int i = 1; i < 10; i++) { 
       (*head+i-1)->next = (*head+i); 
       (*head+i)->value = i; 
       (*head+i)->next = NULL; 
     } 
     curr = *head; 
     printf("done 2\n"); 
     for(int i = 0; i < 10; i++) { 
       printf("%d\t", (*head + i)->value); 
       //curr = curr->next; 
     } 
     printf("\ndone 3\n"); 
     //free(curr); 
     return 0; 
} 

, когда я скомпилировать и запустить код, полученный результат,

done 1 
done 2 
0 1 2 3 154208560 842282289 876087600 154744882 808859448 875837236 
done 3 

Почему я смог присвоить значения 4 узла и доступ к нему, когда я на самом деле создал список размером 3 ?

Я вижу, что значения мусора печатались с доступа 5-го до 10-го узла. Но как создается 4-й узел?

P.S:

Я знаю, что 10 = 3!. Код работал правильно, когда я поставил цикл в свои пределы. Я хотел посмотреть, что произойдет, когда мы выйдем за пределы. Я вижу, что 4-й узел также был создан, так как мне удалось присвоить значение, когда я на самом деле создал список размером 3.

Это чисто, чтобы увидеть, не получится ли я от сбоя или нет.

+0

'10! = 3' ... если я правильно понимаю ваш код. – wildplasser

+3

Доступ за пределами выделенной памяти - это [неопределенное поведение] (https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior). Все может случиться, в том числе работать. – user3386109

+0

Не так ли? Я этого не знал! Я знаю, что 10! = 3. Код работал правильно, когда я поставил цикл в свои пределы.Я хотел посмотреть, что произойдет, когда мы выйдем за пределы. Я вижу, что 4-й узел также был создан, так как мне удалось присвоить значение, когда я фактически создал список размером 3. – Aspirant9

ответ

7

Вы вызываете undefined behavior. Когда вы это сделаете, программа может потерпеть крах, может показаться, что она работает исправно, или она может вести себя, казалось бы, случайным образом.

C не выполняет никаких проверок границ в массивах или выделенной памяти. Это одна из вещей, которая делает ее быстрой. Это также означает, что это позволит вам делать то, что вы не должны делать. Он доверяет программисту «делать правильные вещи».

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

Попытка понять неопределенное поведение, как правило, напрасно. Все зависит от деталей реализации вашего компилятора и машины, на которой он работает. В этом случае записываемая память была, вероятно, нераспределенной памятью в куче после правильно распределенной памяти. В зависимости от того, как реализован malloc, эта часть памяти может содержать данные, необходимые для правильной работы malloc и других функций. Дело в том, что запись за конец массива не гарантирует краха, поэтому вам нужно быть осторожным.

+0

Вы имеете в виду, что значение 4-го узла, которое вы получили, тоже было значением для мусора? – Aspirant9

+0

Нет, моя машина вышла '0 1 2 3 4 5 6 7 8 9'. Кроме того, если я раскомментирую вызов функции «free», программа выйдет из строя. – dbush

+0

Да. Я так понимаю, но как ваша программа смогла присвоить значениям от 3 до 9, когда у вас был массив размером 3? Это связано с тем, что программа пыталась получить доступ к ячейке памяти как указатель структуры к местоположению (узел структуры) и получить доступ к первому местоположению (node-> value) для сохранения данных и, следовательно, данные могли быть сохранены ?? – Aspirant9

1

Этот код будет вести себя по-разному в разных операционных системах.

Вы можете уйти даже с назначением всех 10 целых чисел и правильной печатью.

Ваш код помещает начало списка в кучу с распределением только для 3 элементов.

Вам может повезти и использовать память для всех 10 элементов, или ваша программа выйдет из строя на 4-м!

+0

Запуск вашей программы на https://ideone.com/ Я получил '0 1 2 3 4 5 6 7 8 9' – sg7

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