【问题标题】:c++ struct value appears to change on it's ownc++ struct 值似乎会自行改变
【发布时间】:2017-10-15 00:24:15
【问题描述】:

我只运行了一个简单的代码,但我不断收到“进程完成,退出代码 139(被信号 11 中断:SIGSEGV)” 做一些调试,我发现edges[0].start的值不知何故变成了-2147483644。我发现这种行为很难解释,并且仍然试图找出我在哪里弄错了,但我什至没有更新任何边缘值!无论如何,您能给我的任何提示都会受到极大的重视。您将在下面找到代码。 提前致谢! 温馨的祝福

#include <stdio.h>
#include <climits>
#include "Utils.h"

struct edge {
    int start;
    int end;
    int weight;
};

int main() {
    int n = 4;
    int m = 4;
    edge edges[4] = {
            {2,4,5},
            {4,1,6},
            {1,3,8},
            {3,2,-3}
    };
    int v,e;
    int distance[4];
    // Step 1: initialize graph
    for(v = 0; v < n; v++){
        distance[v] = INT_MAX;
    }
    distance[0] = 0; //source

    // Step 2: relax edges repeatedly
    for(v = 0; v < n; v++){
        for(e = 0; e < m; e++){
            if(distance[edges[e].start] + edges[e].weight < distance[edges[e].end] ){ //relax
                distance[edges[e].end] = distance[edges[e].start] + edges[e].weight;
            }
        }
    }
    // Step 3: check for negative-weight cycles
    for(e = 0; e < m; e++) {
        if (distance[edges[e].start] + edges[e].weight < distance[edges[e].end]) { //shouldn't be able to relax
            std::cout << "Negative cycle detected, please declare war to Paraguay";
        }
    }
    for(v = 0; v < n; v++){
        std::cout << distance[v] << std::endl;
    }
    return 0;
}

【问题讨论】:

  • distance 的有效索引为 0 到 3。edges[e].startedges[e].end 的值为 4。您的程序通过缓冲区溢出表现出未定义的行为。

标签: c++ data-structures segmentation-fault


【解决方案1】:

您的 'n' 和 'm' 迭代器变量定义为 4,但 'edges' 数组的索引介于 0 和 3 之间。您的循环将尝试访问边 [4],从而导致索引超出范围和未定义的行为,这可能是您的起始值损坏的原因。

【讨论】:

    【解决方案2】:

    我实际上不知道为什么,但这对我有用:

    #include <iostream>
    
    struct edge {
        int start;
        int end;
        int weight;
    };
    
    int main() {
        int n = 4;
        int m = 4;
    
        const edge edges[4] = {
                {2,4,5},
                {4,1,6},
                {1,3,8},
                {3,2,-3}
        }; /* <= for my surprise, I'm not get error with this
            *    for indexes of distance[something]
            */
        int v,e;
        int distance[4];
        // Step 1: initialize graph
        for(v = 0; v < n; v++){
            distance[v] = 214748364; // <== with this get fixed
        }
        distance[0] = 0; //source
    
        // Step 2: relax edges repeatedly
            for(v = 0; v < n; v++){
                for(e = 0; e < m; e++){
                    if(distance[edges[e].start] + edges[e].weight < distance[edges[e].end] ){ //relax
                        distance[edges[e].end] = distance[edges[e].start] + edges[e].weight;
                    }
                }
            }
            // Step 3: check for negative-weight cycles
            for(e = 0; e < m; e++) {
                if (distance[edges[e].start] + edges[e].weight < distance[edges[e].end]) { //shouldn't be able to relax
                    std::cout << "Negative cycle detected, please declare war to Paraguay";
                }
            }
            for(v = 0; v < n; v++){
                std::cout << distance[v] << std::endl;
            }
        return 0;
    }
    

    而不是使用distance[v] = INT_MAX; 只需使用distance[v] = 214748364; 或不那么接近INT_MAX 的东西,我得到这个输出:

    0
    8
    13
    16
    Press <RETURN> to close this window...
    

    【讨论】:

    • 我意识到进行更多测试并获得最接近INT_MAX 的值,适用于分配距离是INT_MAX - 52147483642,超过edges[0].start 将获得分配的负值
    • 如果遇到问题并提供解决方案,为什么要在没有任何解释的情况下投反对票?
    【解决方案3】:

    您已经定义了大小为 4 的距离变量

    int distance[4];
    

    虽然边数组的值为:

     edge edges[4] = {
                {2,4,5},
                {4,1,6},
                {1,3,8},
                {3,2,-3}
        };
    

    您正在使用 edge structure 的值来访问每个 distance array. 的单元格 edge 的取值范围是 -3 到 8,而 distance 的取值范围是 0 到 3;这将导致缓冲区溢出并导致应用程序崩溃。

    【讨论】:

    • 不能保证崩溃,它只是未定义的行为。任何事情都可能发生,从看似正常工作到demons flying from your nose
    • 我在 0 到 3 之间的范围内对其进行了测试,但仍然出现错误,在第一次比较中 edges[0].start 变为 -2147483647
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    相关资源
    最近更新 更多