分段错误调试帮助

发布于 2024-12-02 04:29:30 字数 4259 浏览 2 评论 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;
}

I'm trying to implement a simple stack. It works fine on MacOSX but crashes on linux(Ubuntu). Can someone help me to know why?

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧人哭 2024-12-09 04:29:30

有几个不正确的分配。它们仅分配指针大小的内存(在 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));

There are a couple of incorrect allocations. They are only allocating memory the size of a pointer (4 bytes on a 32-bit system) and subsequent initialization of those pieces of memory will overwrite past the end of the allocated memory. The ones I noticed are these:

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

and

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

They should be something like this:

new_element = (element ) malloc(sizeof(struct Element));
new_stack = (stack) malloc(sizeof(struct Stack));
つ可否回来 2024-12-09 04:29:30
    next_element = this_stack->head->next;
    free(this_stack->head->next);
    this_stack->head = next_element;

在循环的下一次迭代中,您访问刚刚被释放的 this_stack->head

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

On the next iteration of the loop, you access this_stack->head, which has just been freed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文