尝试访问向量中对象中的字段时出现段错误

Posted

技术标签:

【中文标题】尝试访问向量中对象中的字段时出现段错误【英文标题】:Segfault when trying to access fields in an object in vector 【发布时间】:2014-10-15 05:30:30 【问题描述】:

这似乎是有史以来最简单的事情,但无论我尝试什么,它都会不断出现段错误。抱歉,如果它很明显且易于搜索,我已经在无数向量段错误线程上搜索了大约 2 个小时,似乎没有人遇到这个确切的问题。

class A

protected:
    std::vector<B> myVector = std::vector<B>(1);
    void doStuff();
;

void A::doStuff()

    myVector.push_back(B());
    myVector[0].initiate();


class B

public:
    int a;
    B();
    void initiate();
;

B::B()



void B ::initiate()

    a = 0; //**this is where segfault happens**

另外,如果我也将向量放入 B 中会怎样?每次我使其中一个组件具有更大的内部向量时,Bs 的向量是否必须完全重新分配?还是会出现段错误?在任何一种情况下,有没有办法为每个向量槽分配固定数量的内存或为我希望增长的对象分配一些东西???

编辑: "A".h

#ifndef PLATE_H
#define PLATE_H

#include "Column.h"
#include <vector>

class World;
class Plate

protected:
    World* myWorld;
    std::vector<Column> vColumns = std::vector<Column>(1); 

“A”.cpp:

void Plate::initiate(unsigned short xDim, unsigned short yDim, World * world)

    myWorld = world;
    dMass = 0;

    for (int x = 0; x < xDim; x++) 
        for (int y = 0; y < yDim; y++) 
            vColumns.push_back(Column());
            std::cout << vColumns.size();
            vColumns[x + y*xDim].initiate(5,myWorld->cMantleDensity,myWorld); //%%%%%%% 5 is temporary
            dMass = dMass + vColumns[x + y*xDim].getDensity() * vColumns[x + y*xDim].getNumGoxels();
        
    

“B”.h:

#ifndef COLUMN_H
#define COLUMN_H
#include <vector>
#include "Goxel.h"

class World;
class Column

protected:
    World* myWorld;
    std::vector<Goxel> vGoxels;
    unsigned char cCrumple;
    unsigned char cVolcanism;
    unsigned short sThickness;
    short sRootDepth;
    float fDensity;
public:
    Column();
    void initiate(unsigned short, unsigned char,World* const);

“B”.cpp:

void Column::initiate(unsigned short thick, unsigned char mantleDensity,World* world)

    myWorld = world;
    cCrumple = 0;
    cVolcanism = 0;
    sThickness = thick;
    fDensity = 58; //basalt
    sRootDepth = (short)(-((sThickness * fDensity) / mantleDensity));

    for (int i = 0; i < thick; i++)
    
        vGoxels.push_back(Goxel());
        vGoxels[i].quickInitiate((char)(((i-1)*58) / 20));
    

【问题讨论】:

发生段错误时调用 B::initiate() 的方法是什么? 您缺少返回类型,即 doStuff();必须是 void doStuff();类似地启动();必须是无效的initial(); 您认为返回类型是垃圾?但是空的默认构造函数不是吗? 一个能实际编译的测试用例是好事... 无法复制:ideone.com/TCkW2X。我不认为我能做到,但我还是跑了。 【参考方案1】:

这样做:

$ gdb a.out
> run
*segfault*
> where

调试器将向您显示段错误实际位置的良好堆栈跟踪,因此您不必猜测。

【讨论】:

我确实有一个堆栈跟踪。它位于 myWorld = world(如果我注释掉 myWorld = world,则为 cCrumple = 0),无论第一次尝试访问实际 Column 对象是什么。

以上是关于尝试访问向量中对象中的字段时出现段错误的主要内容,如果未能解决你的问题,请参考以下文章

[访问 我以前可以访问的功能时出现段错误

C ++:访问unordered_map中的数据时出现段错误以设置

尝试初始化结构数组时出现段错误

访问嵌套结构时出现段错误

删除对象时出现段错误 - GDB 在 free() 中说

初始化数组时出现段错误