【问题标题】:C++ segfault when accessing std::vector.size() of an objects pointer's vector访问对象指针向量的 std::vector.size() 时出现 C++ 段错误
【发布时间】:2016-01-24 12:25:59
【问题描述】:

执行代码时出现段错误:根据 GDB,段错误是由

引发的
Program received signal SIGSEGV, Segmentation fault.
0x00000000004090a6 in std::vector<GeometricObject*, std::allocator<GeometricObject*> >::size (this=0x30)
at /usr/include/c++/4.9/bits/stl_vector.h:655
655       { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }

这就是 GDB where 命令的输出

#0  0x000000000040923c in std::vector<GeometricObject*, std::allocator<GeometricObject*> >::size (
this=0x30) at /usr/include/c++/4.9/bits/stl_vector.h:655
#1  0x000000000040843c in World::hitObjects (this=0x0, r=...)
at /mnt/7DEB96B84D6B013D/Universita/Programmazione ad oggetti e grafica/esercizi/Progetto - RTFGU/core/world/world.cpp:85
#2  0x000000000040a0d8 in MultipleObjects::traceRay (this=0x67ea70, r=...)
at /mnt/7DEB96B84D6B013D/Universita/Programmazione ad oggetti e grafica/esercizi/Progetto - RTFGU/core/tracers/multipleObjects.cpp:13
#3  0x00000000004086f0 in World::renderScene (this=0x7fffffffdd60)
at /mnt/7DEB96B84D6B013D/Universita/Programmazione ad oggetti e grafica/esercizi/Progetto - RTFGU/core/world/world.cpp:115
#4  0x0000000000407c05 in main (argc=1, argv=0x7fffffffdea8)
at /mnt/7DEB96B84D6B013D/Universita/Programmazione ad oggetti e grafica/esercizi/Progetto - RTFGU/main.cpp:20

这里是主类

int main(int argc, char const *argv[]){

World w;

w.build();
w.renderScene();
w.displayImage();


return 0;
}

这里是带有定义的世界级

class World{
public:
 World();
~World();

void addObject(GeometricObject *);
void build();
ShadeRec hitObjects(const Ray &);
void renderScene() const;
void displayImage() const;
void displayPixel(const int, const int, const RGBColor &) const;

RGBColor backgroundColor;
ViewPlane vp;
Tracer * tracer_ptr;
cv::Mat * rendering;
std::vector<GeometricObject*> objects;
};

// definitions

World::World(): backgroundColor(),  vp(), tracer_ptr(0), rendering(0), objects(){}

World::~World(){}

void World::addObject(GeometricObject * o){
objects.push_back(o);
}


void World::build(){
std::cout << "Build begins" << std::endl;

int width = 1024, height = 768;

vp.setHres(width);
vp.setVres(height);
vp.setPixelSize(1.f);
vp.setGamma(1.f);

rendering = new cv::Mat(height,width, CV_8UC3, cv::Scalar(0,0,0));
tracer_ptr = new MultipleObjects(this);

backgroundColor = BLACK;

Sphere * s1 = new Sphere(Point(0., -25., 0.), 80., CYAN);
Sphere * s2 = new Sphere(Point(0.,30.,0.), 60., MAGENTA);
Plane * p = new Plane(Point(0.), Normal(0., 1., 1.), YELLOW);

std::cout << objects.size() << std::endl; // used for debug: size is 0


addObject(s1);
addObject(s2);
addObject(p);

std::cout << objects.size() << std::endl; // used for debug: size is 3

for(uint i = 0; i < objects.size(); i++) // in this scope objects.size() works
 std::cout << objects[i]->toString() << std::endl;

// at this stage gdb give me these information:
(gdb) p this
$1 = (World * const) 0x7fffffffdd60
(gdb) p *this
$2 = {backgroundColor = {r = 0, g = 0, b = 0}, vp = {hRes = 1024, vRes = 768, s = 1, gamma = 1, 
gammaInv = 1}, tracer_ptr = 0x67ea70, rendering = 0x67d870, 
objects = std::vector of length 3, capacity 4 = {0x67ea90, 0x67ead0,  0x67eb10}}
(gdb) p &objects
$4 = (std::vector<GeometricObject*, std::allocator<GeometricObject*> > *) 0x7fffffffdd90

}

ShadeRec World::hitObjects(const Ray & r){

// at this stage , instead
(gdb) p this
$1 = (World * const) 0x0
(gdb) p *this
Cannot access memory at address 0x0
(gdb) p objects
Cannot access memory at address 0x30
(gdb) p &objects
$2 = (std::vector<GeometricObject*, std::allocator<GeometricObject*> > *) 0x30


std::cout << "hitObjects begins" << std::endl;
ShadeRec sr(*this);
int objNum = objects.size(); // in this scope objects.size() throw a segfault
double t, tmin = viewLimit;

for(int i = 0; i < objNum ; i++){
 if(objects.at(i)->hit(r, t, sr) && t < tmin){
  sr.haveHit = true;
  sr.color = objects.at(i)->getColor();
  tmin = t;
 }
}
return sr;
}


void World::renderScene() const{
std::cout << "renderScene begins" << std::endl;

RGBColor col;
Ray ray;
double z = 10;
double x, y;

ray.d = Vect3(0.,0.,-1.);

for(int r = 0; r < vp.vRes; r++)
  for(int c = 0; c < vp.hRes; c++){
    x = vp.s*(c-(vp.hRes-1)*.5);
    y = vp.s*(r-(vp.vRes-1)*.5);
    ray.o = Point(x, y, z);
    std::cout << "debug - " << r << " " << c << std::endl;
    col = tracer_ptr->traceRay(ray);
    std::cout << "exit traceRay" << std::endl;
    rendering->at<cv::Vec3b>(cv::Point(c,r)) =    cv::Vec3b(col.b*255,col.g*255,col.r*255);
  }
}

void World::displayImage() const{

 cv::imwrite("rendering.png", *rendering);

 cv::namedWindow("Rendering", cv::WINDOW_AUTOSIZE );

 if(!rendering->empty())
  cv::imshow("Rendering", *rendering);

 cv::waitKey(0);
}

最后是在 world::renderScene() 中启动 traceRay() 并在其自身中调用 world::hitObject() 的 MultipleObject 类

class MultipleObjects: public Tracer{
public:
  MultipleObjects();
  MultipleObjects(World *);
  ~MultipleObjects();

  RGBColor traceRay(const Ray &) const;

 protected:
  World * world_ptr;
};

// definitions

MultipleObjects::MultipleObjects(): Tracer(){}

MultipleObjects::MultipleObjects(World * w): Tracer(w){}

MultipleObjects::~MultipleObjects(){}

RGBColor MultipleObjects::traceRay(const Ray & r) const{
  ShadeRec sr(world_ptr->hitObjects(r));

  if(sr.haveHit)
    return sr.color;
  else
    return world_ptr->backgroundColor;
}

问题是:为什么在 World::build() 范围内一切正常,而在 World::hitObjects() 中,this 指向 NULL 而 &objects 指向 0x30?

在此先感谢您的回答,并为我糟糕的英语以及我的第一个问题深表歉意。

【问题讨论】:

标签: c++ c++11 segmentation-fault gdb stdvector


【解决方案1】:

看起来你的世界指针无效。

如果您允许 MultipleObjects 类的僵尸状态(也就是没有世界指针),您至少可以将 world_ptr 初始化为 nullptr 并在尝试对其调用任何内容之前对其进行检查。

【讨论】:

    【解决方案2】:

    我发现扩展 Tracer 类的 MultipleObjects 类除了 Tracer 继承的变量外,还有一个 World * world_ptr 变量。 所以当我打电话时:

    tracer_ptr = new MultipleObjects(this);
    

    Tracer 的 World* var 设置为 this,MultipleObjects'S World* var 为空。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-20
      • 1970-01-01
      • 2020-02-07
      • 2020-02-09
      • 1970-01-01
      • 2017-09-20
      相关资源
      最近更新 更多