在运行时期间随机更改数组内容

时间:2014-07-25 19:17:33

标签: c++ arrays memory

我有一个名为SolidObject的类,它包含指向第一个数组元素的各种指针:

// Member declaration and definition pulled together from .cpp and .h
class SolidObject {
    //I will only use one variable as demonstration, the others behave the same
protected:    
    float* vertices;
public:
    SolidObject(float[] vertices) {
        this->vertices = vertices;
    }    
}

对于实验,我曾经将硬编码数组传递给构造函数,例如

float vertices[] {
    -5,0,-5,
    5,0,-5,
    -5,10,-5,
    -5,0,5,
    5,10,-5,
    5,0,5,
    -5,10,5,
    5,10,5
};
SolidObject cube (vertices);

现在我正在将斯坦福PLY文件中的值解析为std::vector,然后将其传递给构造函数:

std::vector<float> vertices;
for (...) {
    vertices.push_back(....);
}
SolidObject cube (&vertices[0]);

使用此方法,cube->vertices中指向的值在运行时期间没有任何原因发生变化。这是watch coinObject->vertices[0]的GDB观察点输出:

这是WP第一次被触发。这是预期的,因为vertices是使用默认(void)构造函数时的NULL指针。 coinObject首先被定义,然后被初始化,所以这种行为是预期的。

Hardware watchpoint 1: coinObject->vertices[0]

Old value = <unreadable>
New value = 0.100000001
0x0000000000409c69 in gameloop (screen=0x689cc0, font=0x84a020)
    at ../gameloop.cpp:386
386     coinObject = SolidObject::fromFile("/home/sebastian/coin.ply");
(gdb) c
Continuing.

现在出现了我无法向自己解释的内容:

Hardware watchpoint 1: coinObject->vertices[0]

Old value = 0.100000001
New value = 0
0x0000003852c8d4b1 in memset () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) c
Continuing.
Hardware watchpoint 1: coinObject->vertices[0]

Old value = 0
New value = 1.40129846e-45
0x00007ffff63df548 in ?? () from /usr/lib/x86_64-linux-gnu/dri/r600_dri.so
(gdb) c
Continuing.

这次在这两次更改后它停止了,有时候coinObject->vertices[0]会有数千次更改。有时程序甚至在第一次或第二次更改后崩溃,因为使用这些数组的OpenGL无法找到224中的百万个顶点。(我使用glDrawElements的索引数组,但这对我的问题不重要...)

任何人都可以解释为什么会发生这种情况以及如何解决它?

1 个答案:

答案 0 :(得分:1)

如果您在对象中使用vector,则代码会更安全:

class SolidObject
{
std::vector<float> vertices;
public:
  SolidObject(const std::vector<float>& original_vertices)
     : vertics(original_vertices)
  {
  }
};

如果您传递给vector版本的SolidObject曾经调整大小,那么指向浮点数的指针将不再有效并指向垃圾。

另外,为什么使用float代替double来降低精确度?

如果您希望SolidObject使用相同的向量,您可以使用引用作为数据成员:

class SolidObject
{
  std::vector<float>& vertices;
  public:
    SolidObject(std::vector<float>& v)
      : vertices(v)
    {
       // Look, no "this" pointer. :-)
    }
};