清理程序时出现分段错误

时间:2014-08-23 19:23:09

标签: c pointers segmentation-fault

我对C很陌生,而且我一直在经历Zed Shaw"艰难学习C"。我有其他语言的经验,但主要是处理自己的内存管理的语言,所以我对其中的一些很新。我构建了this lesson.中描述的游戏并稍微扩展了它,因此我可以在一个类中定义游戏机制并在另一个类中构建地图。我正在尝试构建函数来处理内存管理并释放程序分配的所有堆内存,但是我的程序在清理时会导致分段错误。

我已根据对象超类定义了一个房间对象,如下所示:

struct Room {
    Object proto;

    Monster *bad_guy;

    struct Room *north;
    struct Room *south;
    struct Room *east;
    struct Room *west;
};

typedef struct Room Room;

Object RoomProto;

我在地图被销毁时调用此方法。根据valgrind,该程序在破坏房间 - >北方的线路上导致分段错误。我这背后的想法是,我检查房间是否存在,如果它存在则将其销毁,这样我就可以浏览所有地图并删除每个房间,但不会尝试释放任何空指针。< / p>

void Room_destroy(void *self)
{
    Room *room = self;


    if(room){
        if(room->north){
            room->north->_(destroy)(room->north);
        }
        if(room->south){
            room->south->_(destroy)(room->south);
        }
        if(room->west){
            room->west->_(destroy)(room->west);
        }
        if(room->east){
            room->east->_(destroy)(room->east);
        }
        if(room->bad_guy){
            room->bad_guy->_(destroy)(room->bad_guy);
        }
        room->_(destroy)(room);
    }
}

我试图通过几种方式自己解决问题,例如首先将指针指向null,例如:     房间* n = NULL;     n = room-&gt; north; 然后检查n而不是仅仅是room-&gt; north。我知道这是一个常见的错误,所以我觉得我可能只是错过了关于指针的一些关键点,没有任何双关语。

2 个答案:

答案 0 :(得分:1)

这条线甚至做了什么?那是标准C吗?

if(room->north){
        room->north->_(destroy)(room->north);
    }

这是内存管理的标准方法:

if(pointer != NULL)
{
   free(pointer);
   pointer = NULL;
}

pointer替换为您拥有的任何指针,例如room->north,您就是好人。不要忘记从一开始就将所有指针设置为一块已分配的内存或NULL。

答案 1 :(得分:1)

好的,所以你提供的链接似乎是在C中实现OOP。这很糟糕。 如果您正在尝试学习C,那么首先尝试理解基础知识会更好。这只会让你感到困惑。

现在来看你的代码。我试图理解,这似乎是问题所在。你在做什么

if(room->north){
     room->north->_(destroy)(room->north);
}
...

您正在调用作为参数传递的同一对象的destroy函数。所以你在自己想要释放的记忆中。如果你想这样做,那就做吧

if(room->north){
     room->_(destroy)(room->north);
}
...

我认为这不会导致任何分段错误。

只是一个小建议。不要混淆OOP和C.否则,你将继续面对这样的问题。