2013-03-19 5 views
0

Я пробовал отлаживать эту программу в GDB, но получаю чрезвычайно странную ошибку при сбое (SIGABRT). Это происходит в моей поп-функции, но я понятия не имею, почему. Кто-нибудь может мне помочь? Большое спасибо!Незначительная ошибка при сбое в GDB

Я прошел через GDB, и я считаю, что авария происходит, когда i = 9 и на бесплатной (tmp) в поп-функции.

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

#define SIZE 10 
#define FALSE 0 
#define TRUE 1 


struct linkedStruct 
{ 
    int elem; 
    struct linkedStruct* next; 
}; 

typedef struct linkedStruct linked; 
typedef linked* linkedPtr; 

void push (linkedPtr* hd, int val) 
{ 
    linkedPtr ptr = (linkedPtr) malloc (sizeof(linked)); 
    ptr->elem = val; 
    ptr->next = *hd; 
    *hd = ptr; 
} 

int isEmpty (linkedPtr hd) 
{ 
    if (hd == NULL) 
     return TRUE; 
    else 
     return FALSE; 
} 


int top (linkedPtr hd) 
{ 
    return (hd->elem); 
} 

void pop (linkedPtr hd) 
{ 
    linkedPtr tmp = hd; 
    hd = hd->next; 
    free (tmp); 
} 

void show (linkedPtr hd) 
{ 
    while (hd != NULL) 
    { 
     printf ("%d, ", hd->elem); 
     hd = hd->next; 
    } 
    printf ("\n"); 
} 

int main (int argc, char**argv) 
{ 
    linkedPtr head = NULL; 
    int i; 
    int temp; 

    /* push 10 random values onto the stack showing the stack growing */ 
    for (i = 0 ; i < SIZE; ++i) 
    { 
     temp = rand() % 100; 
     printf ("In main(): temp: %6d\n", temp); 
     push (&head, temp); 
     show (head); 
    } 

    printf ("\n"); 

    /* remove the value from the stack */ 
    while (!isEmpty(head)) 
    { 
     printf ("Top of stack value is: %d\n", top(head)); 
     pop (head); 
    } 
} 
+0

Подсказка: что происходит, когда есть только один элемент? –

+1

Вы знаете, что любые изменения в 'hd' (например,' hd = hd-> next; ') не будут поддерживаться после завершения' pop() ', правильно? – m0skit0

ответ

0

Реальная проблема здесь состоит в том, что изменения в hd не видны вызывающему абоненту, что приводит к free() будет вызван на память, которая уже была освобождена и, таким образом, он производит неопределенное поведение.

Ваш pop() должен выглядеть следующим образом:

void pop (linkedPtr* hd) 
{ 
    linkedPtr tmp = *hd; 
    *hd = (*hd)->next; 
    free (tmp); 
} 

и называется так:

pop(&head); 
+2

'pop()' не будет изменять 'hd', поскольку он передается по значению. – m0skit0

+0

@ m0skit0: Да, я тоже это заметил, немного опоздал. Присвоение 'next' переданному указателю здесь желательно, так как это способ передачи 'NULL' вызывающему. – LihO

+0

исправлено, спасибо большое! – juice

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