从链表中删除项目会导致分段错误,因为稍后会引用释放的内存

问题描述 投票:0回答:1

我正在开发一个简单的游戏,其功能是射击小行星会产生 2 个较小的小行星。 当我删除一颗被击中的小行星,然后尝试添加 2 个新小行星时,我遇到了问题。 这是检查命中的代码(对于所有镜头检查所有小行星)并删除小行星:(我知道代码很抱歉:/)

Meteor check_hits(shot_node** head, node** meteor_head){
    Meteor meteor;
    meteor.meret = -2; 
    if(*head==NULL || *meteor_head==NULL) return meteor; //meteor.meret==-2 any of the heads are null
    shot_node* current_shot;
    shot_node* iw=NULL; //inchworm for shot
    node* current_meteor;
    node* prev_meteor=NULL;

    for(current_shot= *head ; current_shot!=NULL ; current_shot=current_shot->next){
        for(current_meteor = *meteor_head ; current_meteor!=NULL ; current_meteor=current_meteor->next){
            if(SDL_HasIntersectionF(&current_meteor->meteor.position , &current_shot->shot.position)){
                if(iw==NULL){
                    *head = current_shot->next;
                    free(current_shot);
                    current_shot=*head;
                }else{
                    iw->next = current_shot->next;
                    free(current_shot);
                    current_shot=iw;
                }
                meteor = current_meteor->meteor;
                if(prev_meteor==NULL){
                    
                    *meteor_head = current_meteor->next;
                    free(current_meteor); 
                    
                }else{
                    prev_meteor->next = current_meteor->next;
                    free(current_meteor); 
                }
                return meteor; //return data of deleted asteroid
            }
            prev_meteor = current_meteor;
        }
        current_meteor=*meteor_head;
        iw=current_shot;
    }
    meteor.meret = -1;
    return meteor; //meteor.meret==-1 => didnt delete anything
}

我怀疑这里出了问题,因为当我只是删除并且之后没有插入任何内容时就会发生这种情况。当我渲染所有小行星(遍历列表)并且显然试图取消引用 0xfeeefeeefeeefeee 时,就会发生段错误,这是释放内存的标志(或类似的东西)。所以基本上我的列表包含一个已经释放的元素。 我尝试用很多断点来调试它,但没有找到任何模式。

结构体定义:

typedef struct Meteor{
    SDL_FRect position;
    int meret;
}Meteor;

typedef struct node{
    Meteor meteor;
    struct node *next;
}node;

typedef struct{
    double angle;
    SDL_FRect position;
}Shot;

typedef struct shot_node{
    Shot shot;
    struct shot_node* next;
}shot_node;

此函数在此之后被调用两次(meret 表示大小)

if(temp_meteor.meret>=1){
            app->meteor_lista_head=spawnMeteors_pos(app->meteor_lista_head , temp_meteor.position.x+50 , temp_meteor.position.y+50 , temp_meteor.meret-1);
            app->meteor_lista_head=spawnMeteors_pos(app->meteor_lista_head , temp_meteor.position.x-50 , temp_meteor.position.y-50 , temp_meteor.meret-1);
        }
node* spawnMeteors_pos(struct node* head, int x , int y , int meret){
    Meteor meteor;
    meteor.position.x = x;
    meteor.position.y = y;
    meteor.meret = meret;
    meteor.position.h = 32*pow(2 , meteor.meret);
    meteor.position.w = 32*pow(2 , meteor.meret);
    node* uj = (node*) malloc(sizeof(node));
    uj->meteor = meteor;
    uj->next=head;
    return uj;
}
c linked-list segmentation-fault
1个回答
0
投票

问题不在于迭代流星列表后

prev_meteor = NULL;

© www.soinside.com 2019 - 2024. All rights reserved.