我的代码在构建时没有出现任何错误,但无法正常工作

时间:2019-06-03 21:39:31

标签: c++

编译代码时,没有收到任何错误,但是代码无法正常工作。我知道这是因为main末尾的cout不会在控制台上打印任何内容。当我尝试调试时,它指出了不同头文件中的一些问题,例如allocator.h,new_allocator.h,stl_vector.h等。但是,如果我注释掉第109行(说ListaEspVazios LEV(Cntr1);的行) ,cout将预期结果打印到控制台。我还必须说我是编码的新手,如果您能给我一些有关此代码中“不良编码实践”的提示,或有关更好的方法来处理我在此处所做的工作的建议,我将不胜感激。预先感谢!

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;


typedef vector<double> Dimensoes;
typedef vector<double> Coord3D;
typedef vector<Coord3D> Espaco;


class Caixa {
    int index;
    int qtde;
    Dimensoes DimCx;
    double vol;
    double aBase;
    int aloc;
public:
    Caixa(int idx, int qtde, Dimensoes dim);
    double BuscarIndex();
    double BuscarVol();
};

class Container {
    int _index;
    int _qtde;
    Dimensoes DimCntr;
    double _vol;
public:
    Container(int idx, int qtde, Dimensoes dim);
    Dimensoes BuscarDim();
};

class ListaEspVazios {
    vector<Espaco> ListaEspaco;
public:
    ListaEspVazios(Container cntr);
};

class ListaCaixas {
    vector<Caixa> vCaixas;
public:
    ListaCaixas(vector<Caixa> vCx);
    static bool comparaCaixas(Caixa caixa1, Caixa caixa2);
    vector<Caixa>BuscarLista();
};

Caixa::Caixa(int idx, int qtde, Dimensoes dim)
:index(idx), qtde(qtde), DimCx(dim){
    aloc = 0;
    vol = DimCx[1] * DimCx[2] * DimCx[3];
    aBase = DimCx[1] * DimCx[2];
}

double Caixa::BuscarIndex(){
    return index;
}

double Caixa::BuscarVol(){
    return vol;
}

Dimensoes Container::BuscarDim(){
    return DimCntr;
}

Container::Container(int idx, int qtde, Dimensoes dim)
: _index(idx),_qtde(qtde), DimCntr(dim){
    _vol = DimCntr[1] * DimCntr[2] * DimCntr[3];
}

ListaEspVazios::ListaEspVazios(Container cntr){
    Dimensoes dimInicial = cntr.BuscarDim();
    Coord3D PtA = {0, 0, 0};
    Coord3D PtB = dimInicial;
    Espaco Inicial = {PtA, PtB};
    ListaEspaco[0] = Inicial;
}
bool ListaCaixas::comparaCaixas(Caixa caixa1, Caixa caixa2){
        return (caixa1.BuscarVol() > caixa2.BuscarVol());
}

vector<Caixa> ListaCaixas::BuscarLista(){
    return vCaixas;
}

ListaCaixas::ListaCaixas(vector<Caixa> vCx){
    //Ordenando elementos em ordem decrescente de volume
    vCaixas = vCx;
    sort(vCaixas.begin(), vCaixas.end(), comparaCaixas);
}

int main(int argc, char** argv) {

//Inicialização das caixas
    Caixa cx1(1, 2, {0.253, 0.608, 0.518});
    Caixa cx2(2, 3, {0.263, 0.480, 0.323});
    Caixa cx3(3, 10, {0.203, 0.403, 0.413});
    Caixa cx4(4, 4, {0.170, 0.530, 0.380});
    Caixa cx5(5, 1, {0.285, 0.435, 0.255});


//Inicialização do Container
    Container Cntr1(1, 1, {2.48, 10, 3.28});

//Inicialização da Lista de Espaços Vazios no Container
    ListaEspVazios LEV(Cntr1);


//Inicialização da Lista de Caixas
    vector<Caixa> listaCx = {cx1,cx2,cx3,cx4,cx5};
    ListaCaixas LC(listaCx);
    vector<Caixa> listaOrdenada = LC.BuscarLista();

    cout << "The boxes list, ordered by volume is: \n" << "[";
    for (int i=0; i<5;i++){
        cout << listaOrdenada[i].BuscarIndex() << " ";
    }
    cout << "]\n";
    cout << flush;


return 0;
}

2 个答案:

答案 0 :(得分:2)

您的代码中有两个问题:

  1. std::vector的索引在几个地方。例如:

    vol = DimCx[1] * DimCx[2] * DimCx[3];
    

    在C和C ++中,数组和诸如std::vector之类的一般类的索引都从0而不是1开始。

  2. 访问尚不存在的元素:

    ListaEspaco[0] = Inicial;
    

    此处您正在正确访问第一个元素;但是std::vector为空。

如果幸运的话,这两个问题都可能使程序崩溃,或者如果不幸的话,可能只是简单地表现出不良行为。

答案 1 :(得分:1)

问题1-一次错误关闭

您有一个错误的错误。在您的Caixa构造函数中:

Caixa::Caixa(int idx, int qtde, Dimensoes dim)
:index(idx), qtde(qtde), DimCx(dim){
    aloc = 0;
    vol = DimCx[1] * DimCx[2] * DimCx[3];
    aBase = DimCx[1] * DimCx[2];
}

在您的Container构造函数中:

Container::Container(int idx, int qtde, Dimensoes dim)
: _index(idx),_qtde(qtde), DimCntr(dim){
    _vol = DimCntr[1] * DimCntr[2] * DimCntr[3];
}

出了什么问题?当您拥有一个向量或3个元素的数组时,它的元素位于索引0,索引1和索引2:

int main() {
    std::vector<double> values { 3.1415, 2.71828, 0.9999 };

    // First value:
    std::cout << values[0] << '\n'; // Prints 3.1415

    // Second value:
    std::cout << values[1] << '\n'; // Prints 2.71828

    // Third value:
    std::cout << values[2] << '\n'; // Prints 0.9999
}

当您尝试访问DimCx[3]DimCntr[3]时,代码会中断,因为元素3没有任何内容。

问题2-访问空数组中的元素

在下面的函数中,您将Inicial分配给ListaEspaco[0],但是ListaEspaco中没有任何元素。ListaEspaco.data()为空,因此导致段错误。

ListaEspVazios::ListaEspVazios(Container cntr){
    Dimensoes dimInicial = cntr.BuscarDim();
    Coord3D PtA = {0, 0, 0};
    Coord3D PtB = dimInicial;
    Espaco Inicial = {PtA, PtB};
    ListaEspaco[0] = Inicial;
}

我们可以使用push_back将代码添加到ListaEspaco来轻松更改代码:

ListaEspVazios::ListaEspVazios(Container cntr){
    Dimensoes dimInicial = cntr.BuscarDim();
    Coord3D PtA = {0, 0, 0};
    Coord3D PtB = dimInicial;
    ListaEspaco.push_back({PtA, PtB}); 
}

现在运行代码,我得到:

The boxes list, ordered by volume is: 
[1 2 4 3 5 ]

将来要诊断像这样的代码

我在启用Clang编译器的地址清除器的情况下编译了您的代码。这会对其进行编译,以便每当您遇到段错误或访问错误的内存时都会有一个堆栈跟踪!编译命令非常简单:

$  clang++ test.cpp -fsanitize=address

然后,当您运行代码时,它会打印出导致中断的原因的堆栈跟踪。例如,在解决第一个问题之后,这是它显示的错误:

AddressSanitizer:DEADLYSIGNAL
=================================================================
==6265==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000010 (pc 0x000000504810 bp 0x7ffd73e67170 sp 0x7ffd73e67140 T0)
==6265==The signal is caused by a READ memory access.
==6265==Hint: address points to the zero page.
    #0 0x50480f in std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >::capacity() const (/home/me/scratch/a.out+0x50480f)
    #1 0x4fe211 in std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >::operator=(std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&) (/home/me/scratch/a.out+0x4fe211)
    #2 0x4fadf7 in ListaEspVazios::ListaEspVazios(Container) (/home/me/scratch/a.out+0x4fadf7)
    #3 0x4fc5dd in main (/home/me/scratch/a.out+0x4fc5dd)
    #4 0x7fe7a66cbb6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)
    #5 0x41c449 in _start (/home/me/scratch/a.out+0x41c449)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/home/me/scratch/a.out+0x50480f) in std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >::capacity() const
==6265==ABORTING

这告诉我ListaEspVazios::ListaEspVazios(Container)中某处存在导致段错误的错误,而段错误发生在向量构造期间。这就是帮助我缩小错误范围的原因!