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

寻找最优服务器的C++代码本地正常,大学服务器报段错误求助

排查C++代码段错误(Signal 11)问题

我帮你分析下代码里导致段错误的问题,本地运行正常但服务器报错,大概率是内存越界破坏了堆结构,咱们一步步来:

任务背景

要在计算机网络中找出最优服务器节点:该节点到其他所有计算机的最短路径(跳数)的最大值是所有节点中最小的(也就是图的中心节点问题)。

输入输出规则

输入规则

  • 第一行是计算机数量
  • 后续每行是相连的计算机编号
  • 最后一行固定为0 0
    示例输入:
5
5 4
1 2
4 3
1 4
0 0

输出规则

  • 第一行是所有计算机收到消息的最小最长跳数(最优节点的最大跳数)
  • 第二行是所有符合条件的服务器节点编号
    示例输出:
2
1 4

错误现象

本地运行正常,但提交到大学测试服务器后,5个公开测试用例仅2个通过,其余3个触发段错误(signal 11),错误信息如下:

Caught fatal signal 11 stderr *** Error in `solution': corrupted size vs. prev_size: 0x0000000001a36940 ***
======= Backtrace: =========
[0x4bb811] [0x4c47bb] [0x4c7d87] [0x42688e] [0x429f47] [0x42aa4d] [0x400817] [0x49a0b6] [0x49a2aa] [0x401039]
======= Memory map: ========
00400000-005a3000 r-xp 00000000 fd:01 776099 /box/solution
007a2000-007ab000 rw-p 001a2000 fd:01 776099 /box/solution
007ab000-007b0000 rw-p 00000000 00:00 0
01a1f000-01a42000 rw-p 00000000 00:00 0 [heap]
2b1ae7340000-2b1ae7349000 rw-p 00000000 00:00 0
7fffd3bb6000-7fffd3bd7000 rw-p 00000000 00:00 0 [stack]
7fffd3bfb000-7fffd3bfe000 r--p 00000000 00:00 0 [vvar]
7fffd3bfe000-7fffd3c00000 r-xp 00000000 00:00 0 [vdso]
ffffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

你的实现代码

#include <fstream>
using namespace std;
int BreathFirstSearch(int** matrix, int size, int row){//function to walk around matrix and find every path from vertex to vertex
    int pathLen=0;
    int q[size+1], dis[size+1], queue_input = 0, queue_output = 0, look_at;
    bool stop = false;
    for(int i=1;i<=size+1;i++){
        q[i]=0;//queue for element I need to look at
        dis[i]=-1; //to now if I have looked at it and to count how many jumps there are between row vertex and every other vertex
    }
    dis[row] = 0;//the row from matrix can go to itself with 0 jumps
    q[queue_input]=row;
    while(q[queue_output]!=0){
        look_at=q[queue_output];
        queue_output++;
        if(!stop){
            for(int col=1; col<=size; col++){//walking through every matrix collon
                if(matrix[look_at][col]==1 && dis[col]==-1){//if matrix collon has 1 to show that there is string between it and the row element. also check if it have already been ir queue
                    queue_input++;
                    q[queue_input]=col;//add collon to queue
                    dis[col]=dis[look_at]+1;//add +1 to path from row to collon element
                }
            }
        }
        int s=0;
        for(int i=1; i<=size; i++){
            for(int k=1; k<=size; k++){
                if(q[k]==i){
                    s++;//count how many elements row has
                    break;
                }
            }
        }
        if(s==size) stop=true; //if row has as much elements as matrix size, then I know that there wont be more and can stop
    }
    int maxDis = 0;
    for (int i = 1; i <= size; i++){
        if (dis[i] > maxDis){
            maxDis = dis[i];
        }
    }
    return maxDis;//return only farthest distance
}
int main(){
    ifstream fin ("serveris.in");
    ofstream fout ("serveris.out");
    if (fin.is_open()){
        int size, x, y;
        fin >> size; //read size of matrix from file
        int** matrix = new int*[size];
        for(int i = 1; i <= size; ++i){
            matrix[i] = new int[size];
        }
        int *result = new int[size];
        for(int i=1; i<=size; i++){//fill matrix with zeros
            for(int k=1; k<=size; k++){
                matrix[i][k]=0;
            }
        }
        while(fin.good()){
            fin >> x >> y;
            if(x!=0){//fill 1 in their places
                matrix[x][y]=1;
                matrix[y][x]=1;
            }
        }
        for(int row=1; row<=size; row++){//go through every row of matrix
            result[row]=BreathFirstSearch(matrix, size, row);//in result array I put in only farthest path
        }
        int min = result[1];
        for(int i=1; i<=size; i++){//find shortest path between vertex
            if(result[i]<min)min=result[i];
        }
        fout<<min<<endl;
        for(int i=1; i<=size; i++){//find in witch row/s this path was
            if(result[i]==min)fout<< i<<' ';
        }
        for(int i=1; i<=size; i++) delete[] matrix[i];
        delete[] matrix;
        delete[] result;
    }
    fin.close();
    fout.close();
}

问题排查与修复方案

段错误(Signal 11)几乎都是内存访问越界导致的,咱们逐个找问题:

1. 二维数组matrix的内存越界

你在main里分配matrix的代码:

int** matrix = new int*[size];
for(int i = 1; i <= size; ++i){
    matrix[i] = new int[size];
}

new int*[size]创建的指针数组下标范围是0~size-1,但你循环从i=1到i=size,会访问matrix[size]——这超出了数组边界,直接破坏堆内存结构,后续delete时就会触发corrupted size错误。

修复:分配size+1个元素,让下标1~size都可用:

int** matrix = new int*[size+1];
for(int i = 1; i <= size; ++i){
    matrix[i] = new int[size+1]; // 列也分配size+1个元素
}

2. result数组的越界访问

main里result的分配是int *result = new int[size];,下标范围0~size-1,但你后续用result[row](row从1到size),访问了result[size],同样越界。

修复:分配size+1个元素:

int *result = new int[size+1];

3. BFS函数里的队列与循环越界

  • 初始化队列时,你写了for(int i=1;i<=size+1;i++),但q数组长度是size+1,下标范围0~size,访问q[size+1]会越界,改成i<=size。
  • 队列结束条件用while(q[queue_output]!=0)很不安全,如果节点编号有0(虽然题目里是1开始),或者队列指针超出范围,都会出错。应该用队列头尾指针判断:while(queue_output <= queue_input)。
  • 那个stop变量的逻辑完全多余,BFS遍历完所有可达节点后队列自然为空,删掉那部分双重循环统计的代码,既提高效率又避免错误。

4. 文件读取逻辑问题

用while(fin.good())读取会导致多读一次循环,因为读取0 0后fin.good()还是true,直到下一次读取失败才会退出。改成直接判断读取结果,读到0 0就退出:

while(fin >> x >> y) {
    if(x == 0 && y == 0) break;
    matrix[x][y] = 1;
    matrix[y][x] = 1;
}

修复后的完整代码

#include <fstream>
using namespace std;

int BreathFirstSearch(int** matrix, int size, int row) {
    int dis[size+1];
    int q[size+1], queue_input = 0, queue_output = 0, look_at;
    
    for(int i = 1; i <= size; ++i) {
        dis[i] = -1;
        q[i] = 0;
    }
    
    dis[row] = 0;
    q[++queue_input] = row; // 调整队列初始化,避免下标0的问题
    
    while(queue_output < queue_input) { // 用头尾指针判断队列是否为空
        look_at = q[++queue_output];
        for(int col = 1; col <= size; ++col) {
            if(matrix[look_at][col] == 1 && dis[col] == -1) {
                q[++queue_input] = col;
                dis[col] = dis[look_at] + 1;
            }
        }
    }
    
    int maxDis = 0;
    for(int i = 1; i <= size; ++i) {
        if(dis[i] > maxDis) {
            maxDis = dis[i];
        }
    }
    return maxDis;
}

int main() {
    ifstream fin("serveris.in");
    ofstream fout("serveris.out");
    
    if(fin.is_open()) {
        int size, x, y;
        fin >> size;
        
        // 分配size+1个元素,下标1~size可用
        int** matrix = new int*[size+1];
        for(int i = 1; i <= size; ++i) {
            matrix[i] = new int[size+1];
            // 初始化当前行所有元素为0
            for(int k = 1; k <= size; ++k) {
                matrix[i][k] = 0;
            }
        }
        
        int* result = new int[size+1];
        
        while(fin >> x >> y) {
            if(x == 0 && y == 0) break;
            matrix[x][y] = 1;
            matrix[y][x] = 1;
        }
        
        for(int row = 1; row <= size; ++row) {
            result[row] = BreathFirstSearch(matrix, size, row);
        }
        
        int min = result[1];
        for(int i = 1; i <= size; ++i) {
            if(result[i] < min) {
                min = result[i];
            }
        }
        
        fout << min << endl;
        for(int i = 1; i <= size; ++i) {
            if(result[i] == min) {
                fout << i << ' ';
            }
        }
        
        // 释放内存
        for(int i = 1; i <= size; ++i) {
            delete[] matrix[i];
        }
        delete[] matrix;
        delete[] result;
    }
    
    fin.close();
    fout.close();
    return 0;
}

内容的提问来源于stack exchange,提问作者Arnita Ziemele

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:08:41