You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac HighSierra下C++队列程序入队时触发Segmentation fault 11

Segmentation Fault 11 原因分析与代码修复(队列实现)

嘿,我看到你在Atom里用GCC写队列程序时,执行入队操作触发了Segmentation fault 11——这是典型的内存访问越界问题,咱们一步步拆解问题并修复:

核心错误:入队操作访问非法内存

你的inqueue()函数里,当队列为空时(此时antrean.akhir = -1),直接执行了antrean.data[antrean.akhir] = elemen;——这意味着你在访问数组的**-1索引**,完全超出了data[MAX]的合法范围(数组合法索引是0到MAX-1),直接触发段错误。

正确的逻辑应该是:队列为空时,先把awal和akhir都重置为0,再给data[akhir]赋值,之后再自增akhir。

其他需要修正的逻辑问题

除了核心的段错误,代码里还有几个小问题也会导致异常或逻辑错误:

  • isfull()判断逻辑偏差:当前只检查akhir == MAX-1,但结合你的入队逻辑,akhir最终会指向队列的下一个空位置,所以应该判断akhir == MAX才是真正的满队状态。
  • totalarray()非法内存访问:循环从i=-1开始,同样会访问data[-1]触发错误,应该从队列的起始索引awal开始遍历。
  • cari()输出错误:你把找到的元素值加1输出了(antrean.data[i]+1),这不是索引位置,应该改为i - antrean.awal + 1(显示为队列中1开头的位置)。
  • 主菜单逻辑混乱:菜单里选项7是“Rata-rata Array”(计算平均值),但代码里case 7直接exit(0),会导致用户选平均值时直接退出程序,需要调整。
  • cari()的状态判断遗漏:原代码没有处理“元素未找到”的提示,会导致空输出。

修正后的完整代码

#include<iostream>
#include<stdlib.h>
#define MAX 5
using namespace std;

struct queue{
    int data[MAX];
    int awal, akhir;
}antrean;

void first(){
    antrean.awal = -1;
    antrean.akhir = -1;
}

bool isfull(){
    // 修正:akhir指向空位置,等于MAX时队列已满
    if(antrean.akhir == MAX){
        return true;
    }else{
        return false;
    }
}

bool isempty(){
    if(antrean.akhir == -1){
        return true;
    }else{
        return false;
    }
}

void tampildata(){
    if(!isempty()){
        // 遍历到akhir-1,因为akhir是下一个空位置
        for(int i=antrean.awal; i < antrean.akhir; i++){
            cout<<antrean.data[i]<<" | ";
        }
    }
    cout<<endl;
}

void inqueue(){
    int elemen;
    if(!isfull()){ // 修正:入队前先检查队列是否已满,而非是否为空
        cout<<"input data : ";
        cin>>elemen;
        if(isempty()){
            // 队列为空时,初始化起始索引为0
            antrean.awal = 0;
        }
        // 给当前akhir位置赋值,再自增
        antrean.data[antrean.akhir] = elemen;
        antrean.akhir++;
        cout<<"data berhasil ditambah"<<endl;
        tampildata();
    }else{
        cout<<"Queue penuh"<<endl;
    }
}

void dequeue(){
    tampildata();
    if(!isempty()){
        cout<<"mengambil data "<<antrean.data[antrean.awal]<<endl;
        for(int i=antrean.awal; i < antrean.akhir-1; i++){
            antrean.data[i] = antrean.data[i+1];
        }
        antrean.akhir--;
        // 如果队列空了,重置awal和akhir
        if(antrean.akhir == 0){
            antrean.awal = -1;
            antrean.akhir = -1;
        }
    }else{
        cout<<"antrean empty"<<endl;
    }
}

void cari(){
    if(!isempty()){
        int cari;
        bool state = false;
        cout << "Data yang dicari :";
        cin >> cari;
        for(int i = antrean.awal; i < antrean.akhir; i++){
            if (antrean.data[i] == cari) {
                // 修正:输出队列中的位置(从1开始计数)
                cout << "Data ditemukan pada posisi ke-:" << i - antrean.awal + 1 << endl;
                state = true;
                break;
            }
        }
        if(!state){
            cout << "Data tidak ditemukan" << endl;
        }
    } else{
        cout << "Antrean kosong" << endl;
    }
}

void totalarray(){
    if(isempty()){
        cout << "Antrean kosong, tidak bisa menghitung total" << endl;
        return;
    }
    int temp = 0;
    // 修正:从awal开始遍历到akhir-1
    for(int i=antrean.awal; i < antrean.akhir; i++){
        temp += antrean.data[i];
    }
    cout << "Total nilainya :" << temp << endl;
}

// 新增计算平均值的函数
void ratarata(){
    if(isempty()){
        cout << "Antrean kosong, tidak bisa menghitung rata-rata" << endl;
        return;
    }
    int total = 0;
    int count = antrean.akhir - antrean.awal;
    for(int i=antrean.awal; i < antrean.akhir; i++){
        total += antrean.data[i];
    }
    cout << "Rata-rata nilainya :" << (double)total / count << endl;
}

int main(){
    int pilihan, elemen;
    first();
    do{
        tampildata();
        cout<<"1. Init"<<endl
            <<"2. inQueue"<<endl
            <<"3. deQueue"<<endl
            <<"4. tampil data"<<endl
            <<"5. Cari data"<<endl
            <<"6. Total nilai"<<endl
            <<"7. Rata-rata Array"<<endl
            <<"8. Nilai terbesar"<<endl
            <<"9. Nilai terkecil"<<endl
            <<"10. Clear"<<endl
            <<"11. Keluar"<<endl;
        cout<<"input pilihan :";
        cin>>pilihan;
        switch(pilihan){
            case 1:
                first();
                break;
            case 2:
                inqueue();
                break;
            case 3:
                dequeue();
                break;
            case 4:
                tampildata();
                break;
            case 5:
                cari();
                break;
            case 6:
                totalarray();
                break;
            case 7:
                ratarata();
                break;
            case 11:
                exit(0);
            default:
                cout<<"Pilihan tidak valid"<<endl;
        }
    } while(pilihan != 11);
    return 0;
}

关键修改说明

  1. 入队函数修正:入队前先检查队列是否已满,队列为空时初始化awal为0,彻底避免访问负索引。
  2. 出队函数修正:队列清空后重置awal和akhir为-1,保持空队状态的一致性。
  3. 遍历逻辑统一:所有涉及队列元素遍历的函数,都从awal开始到akhir-1结束,杜绝越界风险。
  4. 菜单逻辑修正:把退出程序的逻辑移到选项11,选项7改为调用新增的平均值计算函数,匹配菜单描述。

现在你编译运行这个修正后的代码,入队操作就不会触发Segmentation fault了,其他功能也能正常工作。

内容的提问来源于stack exchange,提问作者Fikar Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:54:10