2015-11-22 3 views
0

Я пытаюсь написать программу, которая находит все выражение ")" в выражении и помещает их в связанный список, всегда добавляя в начале списка. Проблема в том, что когда я пытаюсь поместить новый элемент в список, программа перестает работать.не удалось вставить элемент в соответствующий список

с образцом пользовательского ввода 865)987:

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

typedef struct element { 
    char data; 
    struct element *next; 
} ELEMENT; 


int main(void) 
{ 
    ELEMENT *first = NULL; 
    ELEMENT *new_a; 

    char input[30]; 
    int x=0; 

    printf("Input expression: "); 
    scanf("%s", &input); 

    while(input[x]!='\0'){ 
     if (input[x]==')'){ 
      printf("%c", input[x]);  //This works just fine. 
      new_a->data = input[x];  //Here, the program stops working. 
      new_a->next = first; 
      first = new_a; 
     } 
     x++; 
    } 
} 

Что я делаю не так?

ответ

4
new_a->data 

эквивалентно

(*new_a).data 

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

Для того, чтобы исправить это, необходимо выделить память для new_a:

  1. Выделяют пространство в стеке. Это будет работать, только если связанный список используется исключительно в main, поскольку область локальных переменных only embraces the beginning and end of a function.
    Делают это так:

    ELEMENT new_a; 
    
    ... 
    
    new_a.data = input[x]; 
    new_a.next = first; 
    first = &new_a; 
    
  2. Использование malloc. Это, как правило, используется для связанных списков и применят для связанного списка существующего до самого окончания вашей программы, потому что это сфера независимая:

    ELEMENT* new_a = malloc(sizeof(ELEMENT)); 
    

    Не забудьте free потом!


Примечания:

  • Passing input to scanf suffices; отсутствие необходимости &input.
  • Ваш scanf уязвим для переполнения буфера. Использовать

    scanf("%s29", input); 
    

    вместо этого. Читайте также this.

+0

Спасибо большое, теперь, кажется, работает!Просто небольшая проблема: в строке есть новое предупреждение: «first = &new_a;», «назначение из несовместимого типа указателя». Вы случайно не знаете, почему это так? – DerekT

+0

@DerekT ** Либо ** выделить в стеке с помощью 'ELEMENT new_a;' ** (обратите внимание на отсутствие звездочки!) ** и использовать 'first = &new_a;' ** или ** выделить в бесплатном хранилище с ' malloc' и используйте 'first = new_a;'. Или что-то еще? Если ваша проблема не устранена, * добавьте сообщение об ошибке *, пожалуйста. – Downvoter

0

Вам нужно выделить память для new_a:

new_a = malloc(sizeof(ELEMENT)); 
0

Как ранее ответил, правильный код:

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

typedef struct element { 
    char data; 
    struct element *next; 
} ELEMENT; 

int main(void) 
{ 
    ELEMENT *first = NULL; 
    char input[30]; 
    int x=0; 

    printf("Input expression: "); 
    scanf("%s", &input); 

    while(input[x]!='\0'){ 
     if (input[x]==')'){ 
      ELEMENT *new_a = (ELEMENT*)malloc(sizeof(ELEMENT)); 
      printf("%c", input[x]); 
      new_a->data = input[x]; 
      new_a->next = first; 
      first = new_a; 
     } 
     x++; 
    } 
} 
+0

scanf ("% s", & input); должен быть scanf ("% s", input) ;, не нужно указывать возвращаемое значение malloc. и для согласованности должно быть возвращено 0 в основном – amdixon

+0

@amdixon Причина, вы правы! Но я просто скопирую код атора и исправлю ошибку добавления узлов в список. Тем не менее, я думаю, что отличное возвратное значение malloc лучше не делать этого. –

+0

@AntonTodua, на самом деле, это не лучше http://stackoverflow.com/a/605858/817643 – StoryTeller

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