2013-07-26 2 views
-2

У меня есть ниже программа для вставки узла в BSTкопирование данных на значение узла в с дает ошибку сегментации, но таНос удаляет его

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


struct node { 
    int key; 
    struct node * left; 
    struct node * right; 
}; 

struct node * insert(struct node *,int); 

int main(int argc, const char *argv[]){ 
    struct node *root= malloc(sizeof(struct node)); 

    int x; 

    if(root==NULL){ 
     printf("mem error"); 
     return; 
    } 
    root=NULL; 


    while(1){ 
     fprintf(stdout, "Enter the value of data\n"); 
     fscanf(stdin,"%d",&x); 
     root=insert(root,x); 

    } 


} 

struct node * insert(struct node * root, int data){ 

    if(root==NULL){ 
     struct node *root= malloc(sizeof(struct node)); 
     root->key = data; 
     printf("hiii\n"); 
     root->left = NULL; 
     root->right = NULL; 
     return root; 
    }else{ 
     if(root->key >= data){ 
      root->left = insert(root->left,data); 
     }else if(root->key <= data){ 
      root->right = insert(root->right,data); 
     } 
     return root; 
    } 
} 

она работает нормально .. но если я закомментируйте таНос строку в функции вставки ..it дает мне ошибку сегментации после принятия первого значения. Что здесь происходит??

+2

Почему вас удивляет, что отключение 'malloc' в' insert' дает ошибку сегментации? Чего вы ожидали? – zwol

+2

Узнайте немного о форматировании кода при отправке вопроса здесь. Я исправил это для вас. Вы можете посмотреть, что я сделал, нажав кнопку «Изменить». В основном я удалил все пустые строки, которые никто не хочет видеть, и отложил все 4 пробела, щелкнув маленький значок '{}'. Вы получите лучшие ответы с лучшим вопросом. –

ответ

1

Вы не можете комментировать malloc-line в функции вставки. Использование malloc() предназначено для динамического выделения новой памяти для добавления новых узлов в связанный список.

Read: void* malloc (size_t size);

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

Поэтому предположим, если Вы прокомментируете/удалить таНос строку в insert() (читай комментарий):

//struct node *root= malloc(sizeof(struct node)); 
root->key = data; // here illegal operation 

root->left = NULL; // here illegal operation 
root->right = NULL; // here illegal operation 

то root значение будет мусор и вы доступа и выполнять операции чтения действия/записи на мусорный адрес не выделено в процессе - незаконная операция памяти.

Ваш код будет скомпилирован, поскольку по синтаксису правильный код, но во время выполнения ОС обнаружит незаконный доступ к памяти и может завершить ваш код. (интересно отметить: поскольку ОС обнаруживает нарушение прав памяти с помощью процесса - неверный доступ к действительной памяти дает: SIGSEGV И доступ к недействительному адресу дает: SIGBUS). - Фактически это вызывает неопределенное поведение. В худшем случае ваша программа может казаться выполненной без каких-либо сбоев, создавая результаты мусора.

Это дает мне ошибку сегментации после принятия первого значения. Что здесь происходит?

Как я уже объяснял выше, удаление malloc() делает вашу программу ведет себя в неопределенном порядке (читай: Undefined behaviour). Если программа работает как неопределенное поведение, вы можете догадаться, что может случиться, в худшем случае ваша программа может выполняться без каких-либо сбоев или может выполняться частично (это то, что вы наблюдаете). Дело в том, что когда ОС обнаруживает незаконный доступ к памяти и посылает сигнал для завершения процесса. (может быть первое пять значений случайного мусора до root указывает на память, связанную с нашей программой, и согласно OS доступ к этой памяти не является незаконным оператором - в то время как в пятом случае случайное значение root - это память, которая не принадлежит процесса и операции чтения/записи в этой памяти, обнаруженной ОС, поэтому ваш код, наконец, заканчивается с ошибкой сегментации).

+0

читать: [Неопределенное поведение] (http://en.wikipedia.org/wiki/Undefined_behavior) –

+0

.. Спасибо за ответ ... Мое сомнение в этом. У меня уже есть malloc переменный корень в главном функция. Теперь эта же переменная является первым параметром функции insert(). Итак, переменная узла в insert() должна иметь такое же значение? Зачем нужна malloc снова ?? –

+0

@PranabBoruah, как я объяснил в первой строке * 'Использование malloc() предназначено для динамического размещения новой памяти для новых узлов для вставки в связанный список.' * Вам нужна новая память для новых узлов для добавления в связанный список 'malloc () '- системный вызов, который запрашивает систему исполнения, чтобы выделить ее в память данного размера. –

1

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

if(root==NULL) { 
    //struct node *root= malloc(sizeof(struct node)); 
    root->key = data; 

который разыменовывает в NULL указатель. Это приводит к неопределенному поведению. На этом этапе все может случиться. Авария была бы наиболее полезной и очень вероятна, но не гарантирована. Если ваш вопрос говорит о том, что вам удается писать до root->key, это возможно, но не рассчитывайте на то, что он работает с различными сборками или разными хостами (или даже с разными прогонами той же программы на одном компьютере).

+0

Но это не крушение .... вот в чем вопрос. – Jiminion

+0

@Jim Вопрос гласит: «Но если я прокомментирую строку malloc в функции вставки, она дает мне ошибку сегментации». Я воспринял это как означающее ... ну, что я сказал в своем ответе. Как вы интерпретируете заявление? – simonc

+0

Я думаю, он спрашивает, почему он не сработал сразу. – Jiminion

1

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

+0

Но это не то, что происходит. – Jiminion

+0

@Jim В какой части вы не согласны с ... словами для очевидного нового OP. –

+0

Программа, похоже, не сразу сработала. Он делает это через одну итерацию. – Jiminion

0

Вам, кажется, нравится выбрасывать память из окна! В основной:

struct node *root= malloc(sizeof(struct node)); // reserve some memory 
if(root==NULL)         // make sure that memory is reserved 
{ 
    printf("mem error"); 
    return; 
} 
root=NULL;          // loose the address of the memory 

Это должно быть просто:

struct node *root = NULL; 
0

Когда корень NULL, обращаясь к корневой элемент-> ключ поставить вас в очень проблематичной части памяти. Вашей программе удалось пережить одну итерацию перед сбоем.

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

  • Нет связанных вопросов^_^