2011-08-26 63 views
0

我试图实现一个简单的堆栈。它在MacOSX上正常工作,但在Linux(Ubuntu)上崩溃。有人可以帮我知道为什么吗?分段错误调试帮助

MYStack.h

#ifndef MYSTACK_H_ 
#define MYSTACK_H_ 

typedef struct Element *element; 
typedef struct Stack *stack; 

struct Element { 
    struct Element *next; 
    void *data; 
}; 

struct Stack { 
    struct Element *head; 
    unsigned int count; 
    void (*dump) (void *); 
}; 

/* Define boolean type */ 
typedef signed char  bool; 
#define YES    (bool)1 
#define NO    (bool)0 

/* utility macro */ 
#define ELEMENT_NEXT(E)  ((E) = (E)->next) 
#define ELEMENT_DATA(E)  ((E)->data) 
#define STACK_HEAD(S)  ((S)->head) 
#define STACK_SIZE(S)  ((S)->count) 

/* Functions prototypes */ 
bool push(stack , void *); 
bool pop(stack , void **); 
bool create_stack(stack , void (*) (void*)); 
bool delete_stack(stack ); 
void dump_stack(stack); 

#endif /* MYSTACK_H_ */ 

MYStack.c

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include "MYStack.h" 

/* Creating the stack */ 
bool create_stack(stack new_stack, void (*dump_function) (void*)) 
{ 
    new_stack->head = NULL; 
    new_stack->dump = dump_function; 
    new_stack->count = 0; 

    return YES; 
} 

/* Deleting the stack */ 
bool delete_stack(stack this_stack) 
{ 
    element next_element; 

    while (this_stack->head) { 
     next_element = this_stack->head->next; 
     free(this_stack->head->next); 
     this_stack->head = next_element; 
    } 

    return YES; 
} 

/* Dump the stack */ 
void dump_stack(stack this_stack) 
{ 
    element e; 
    int i; 

    e = STACK_HEAD(this_stack); 

    if (this_stack->dump) {  
     for (i = 0; i < this_stack->count; i++) { 
      (this_stack->dump) (e->data); 
      if (e->next != NULL) 
       e = e->next; 
     } 
    } 
} 

/* Adding element to the stack */ 
bool push(stack this_stack, void *data) 
{ 
    element new_element; 
    void (*temp_dump) (void *); 

    this_stack->dump = temp_dump; 

    new_element = (element) malloc(sizeof(element *)); 

    if (new_element == NULL) { 
     fprintf(stdout, "malloc() new element failed : %d\n", errno); 

     return NO; 
    } 

    new_element->data = data; 
    new_element->next = (this_stack)->head; 
    (this_stack)->head = new_element; 
    this_stack->dump = temp_dump; 
    (this_stack)->count++; 

#ifdef DEBUG 
    fprintf(stdout, "Inserting at the stack in the address %p\n", new_element->data); 
#endif 

    return YES; 
} 

/* Remving element from the stack */ 
bool pop(stack this_stack, void **data) 
{ 
    element delete_me; 
    void (*temp_dump) (void *); 

    this_stack->dump = temp_dump; 
    delete_me = this_stack->head; 
    if (delete_me == NULL) { 
     fprintf(stdout, "stack is empty\n"); 
     return NO; 
    } 

    *data = delete_me->data; 
    this_stack->head = delete_me->next; 
    this_stack->dump = temp_dump; 
    this_stack->count--; 

    free(delete_me); 

#ifdef DEBUG 
    fprintf(stdout, "Removing from the stack in the address %p\n", delete_me->data); 
#endif 

    return YES; 
} 

/* Dump function test */ 
void dump_ints(void* data) 
{ 
    int* int_data_ptr = (int*)data; 
    printf("We are dumping an int data : %d\n", *int_data_ptr); 
} 

/* To test our stack */ 
int main (int argc, char const **argv) 
{ 
    stack new_stack; 
    void (*dump_func_ptr) (void*); 
    int i; 
    int stack_ints[] = {1, 2, 3, 4}; 
    void *deleted_item; 

#ifdef DEBUG 
    fprintf(stdout, "We are in debug mode...\n"); 
#endif 

    new_stack = (stack) malloc(sizeof(stack *)); 
    dump_func_ptr = dump_ints; 
    create_stack(new_stack, dump_func_ptr); 
    /* Insert to the stack */ 
    for (i = 0; i < 4; i++) 
     push(new_stack, &stack_ints[i]); 

    /* Print the number of elements */ 
    printf("Our stack contain %d elements\n", new_stack->count); 
    /* Dump the stack */ 
    dump_stack(new_stack); 
    /* Removing some data */ 
    pop(new_stack, &deleted_item); 
    /* Dump the stack */ 
    dump_stack(new_stack); 
    /* Deleting the stack */ 
    //delete_stack(new_stack); 

    free(new_stack); 

    return 0; 
} 
+1

它在哪里崩溃? – BlackBear

+0

教你钓鱼:使用valgrind –

+0

感谢您的回复,我使用valgrind和gdb(backtrace)它在void dump_stack(stack this_stack)函数上崩溃。 – funnyCoder

回答

1

有几个不正确的分配。它们只分配一个指针大小的内存(32位系统上的4个字节),随后这些内存块的初始化将覆盖超过分配内存的末尾。我注意到的有这些:

new_element = (element) malloc(sizeof(element *)); 

new_stack = (stack) malloc(sizeof(stack *)); 

他们应该是这样的:

new_element = (element) malloc(sizeof(struct Element)); 
new_stack = (stack) malloc(sizeof(struct Stack)); 
+0

谢谢你,我的问题现在已经解决了:) – funnyCoder

1
next_element = this_stack->head->next; 
    free(this_stack->head->next); 
    this_stack->head = next_element; 

在循环的下一个迭代,您可以访问this_stack->head,刚刚被释放。

+0

感谢也许delete_stack函数需要修复,但为什么这次在Linux上的崩溃(删除功能从来没有在我的测试主叫!) – funnyCoder

+0

为什么你声明变量'temp_dump'并做'this_stack-> dump = temp_dump; '?你从来没有将'temp_dump'初始化为任何有效的值。我相信你有任务倒退。 –

+0

你是对的:),我不知道为什么我把它添加到我的代码中,现在它只显示:我们的堆栈包含4个元素! – funnyCoder