通过std :: vector.data()指向std :: vector' s元素指向损坏的数据

时间:2016-04-04 08:38:32

标签: c++ c++11 vector dynamic-arrays

ON-TOPIC EDIT:这个问题是关于一个超出范围的std :: vector(在函数内定义),但是通过std ::返回了指向其第一个元素的指针vector.data()。尝试使用返回指针指向的数据最终导致数据损坏,因为std :: vector中的数据已经超出范围并被释放。 E.g:

...
type *ptr;
type* function1(){
     std::vector<type> vector;
     return vector.data();
}
ptr = function1();
// ptr points to corrupt data here
...

ON-TOPIC SOLUTION:&#34; WAY A &#34;下面写的是一个解决方案,但它暂时复制数据。另一件事是,例如:

...
std::vector<type> vect;
void function1(std::vector<type> &vector){
     // Add data to vector
}
// Use the data inside vector
type *ptr = vect.data();
...

旧问题 ......

背景的背景:我正在编写这个引擎,我将位置,法线,顶点和索引数据存储在Mesh类中。我使用所需OpenGL类型的动态数组,如下所示:

class Mesh(){   
    ... 
    GLfloat *vertices;   
    GLubyte *indices;   
    ...
}

我设计了一个带有笔和纸的立方体,其顶点,纹理坐标,法线和索引,然后用这些数据填充我的动态数组(手动复制它,std ::在适当的内存后将其复制到动态数组中分配(使用新的顺便说一句)。这就像一个魅力。立方体完美呈现如下:

...
glEnableClientState(GL_VERTEX_ARRAY);    
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
... 
glVertexPointer(3, GL_FLOAT, 0, meshInst->pos_coords);    
glTexCoordPointer(2, GL_FLOAT, 0, meshInst->tex_coords);
...
glDrawElements(
        GL_TRIANGLES, (CORRECT index count), GL_UNSIGNED_BYTE,
        meshInst->indices
    );
...

背景: 我为Mesh创建了另一个构造函数,而不是将数据复制到GLfloat,GLubyte等数组中新分配的内存中。( 就像魅力一样,我可能会重复 ),它执行以下操作:
1)将文件中的数据( 已彻底测试以正确导入 )加载到std::vector<GLfloat> positionsstd::vector<GLubyte> inds等。
2)我尝试了两种方法将数据传递给我的动态数组,由OpenGL渲染,方式A和方式B:

方式A:

std::copy(positions.begin(), positions.end(), vertices);
std::copy(inds.begin(), inds.end(), indices);

结果:在第一个构造函数中完美地工作 DATA PRINT:

P[72] = { 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1 }
I[36] = { 0, 1, 2, 3, 2, 1, 6, 4, 7, 5, 7, 4, 10, 8, 9, 11, 9, 8, 13, 12, 15, 14, 15, 12, 17, 16, 19, 18, 19, 16, 23, 20, 21, 22, 21, 20 }

方式B:

vertices = positions.data();
indices = inds.data();

结果:没有画画
DATA PRINT:

P[72] = { 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1 }
I[36] = { 0, 1, 2, 3, 2, 1, 6, 4, 7, 5, 7, 4, 10, 8, 9, 11, 9, 8, 13, 12, 15, 14, 15, 12, 17, 16, 19, 18, 19, 16, 23, 20, 21, 22, 21, 20 }

问题是......为什么?在我看来,问题出在OpenGL内部,主要是因为&#39; std :: vector&#34; s保证以与向量&#34;表示的顺序相同的顺序存储在连续的存储位置中。如http://www.cplusplus.com/reference/vector/vector/data/中所述。如果我比较&#39;顶点&#39;指向的数据呢?和&#39;指数&#39;,它实际上完全相同。自己比较两种数据打印。它们都是在加载后使用存储长度和动态数组指针打印的。

非常感谢你的时间,请不要再回答,我喜欢学习。 PS:原谅我的英语,这是我的第二语言。

1 个答案:

答案 0 :(得分:0)

可能你的std::vector超出了范围。由于glVertexPointer不会创建深层副本,而只是存储您必须确定的指针,因此当您想从中绘制时,原始向量仍然存在。

推荐的解决方案:将数据传输到顶点缓冲区对象中,然后您不再需要处理这样的问题,也可以获得更好的性能。