指向数组的指针,我缺少什么?

时间:2011-06-20 21:14:39

标签: c++ arrays opengl pointers

我对OpenGL比较陌生,并且一直在使用它提供的GLTools库。其中一个类GLTriangleBatch部分处理批量顶点。该类有一个全局属性指针pVerts,声明如下:

typedef float M3DVector3f[3];
M3DVector3f *pVerts; 

当调用初始化函数时,上面的指针被委托一个内存块,其中索引的数量是作为参数提供给函数的int(nMaxIndexes):

pVerts = new M3DVector3f[nMaxIndexes];

另一个函数给出了一个由3个M3DVector3fs组成的数组,它们包含一个三角形的顶点。此函数确定将哪些个别顶点添加到批次中。

例如,如果要添加的点已经存在于pVerts中,则pVerts中该点的索引将添加到另一个数组中,该数组包含将要绘制的所有点的索引。因此pVerts仅包含唯一的点。因此,pVerts的实际索引永远不会达到nMaxIndexes。

但是,如果它是一个唯一的顶点,它将被添加到pVerts中,如下所示:

memcpy(pVerts[nNumVerts], verts[iVertex], sizeof(M3DVector3f));

其中nNumVerts是pVerts的当前索引,verts []是3个M3DVector3f的数组,它包含添加的三角形,iVertex是添加的特定顶点的索引。

现在我使用另一个函数来计算顶点的位置以构建(粗糙)球体。我在我的程序中构建的球体以nMaxIndexes = 2028结束,当球体完成时nNumVerts = 378。

现在遵循所有这些,我假设pVerts指向一个范围为0到2027的索引数组,但只有索引0到377填充了数据。但是当我在添加所有顶点后直接放置断点时,pVerts只指向一个M3DVector3f。

我计划将此球体用作可碰撞边界,因此我需要访问这些单独的每个点。我添加了一个返回pVerts的getVertices函数,但返回的指针只指向一个M3DVector3f?我错过了什么?

2 个答案:

答案 0 :(得分:1)

pVerts是指向M3DVector3f类型变量的指针。我怀疑您的调试器正确地向您显示M3DVector3f指向的pVerts(即数组的第一个元素)。这并不一定意味着存在错误:C和C ++中的数组不带任何内部大小信息,因此无法检查“数组对象”,只能查看指定地址的内存。

答案 1 :(得分:1)

这不是3D图形或OpenGL问题,而是缺乏对C和C ++中数组如何工作的理解。

C中的数组是由系统内存支持的一组有余地址空间。内容通过基指针和对该基指针的偏移量通过称为指针算法的机制来寻址。

Say pT类型的指针,用C语法编写T *p。现在让p指向n类型T元素的一些重点内存,分配给new T[n](C ++)或malloc(sizeof(t))。要访问第i个元素,您需要该元素的地址,并取消引用指向该地址的指针。 C有一种称为指针算法的机制:p + i被评估为指向p开始的一组连续元素中第i个元素的指针。要获取元素的值,您必须使用*运算符取消引用:*(p+i)。索引运算符[]提供了简写形式,实际p[i]*(p+i)完全相同。

这是一个鲜为人知的事实,并产生了有趣的后果。指针算术通勤,即p + i == i + p并将其应用于索引运算符,人们会期望实际情况为p[i] == i[p]

回到原来的问题:你正在使用C ++,所以我建议你根本不用手动分配的数组。相反,您最好使用标准容器,即 std :: vector ,可通过#include <vector>获得(无尾随.h!)

而不是M3DVector3f *pVerts只是一个指针,而不是一个完整的限定数组(!),你编写std::vector<M3DVector3f> Verts,这实际上就是你所谓的数组(C ++ STL将其称为向量将它与普通数组区分开来;这可能听起来很奇怪,但是一旦你从更高的数学观点理解了向量空间它实际上是有道理的)。您应该能够在向量元素(即memcpy(...))上使用赋值运算符=,而不是Verts[nNumVerts] = verts[iVertex]。如果编译器抱怨,请重载赋值运算符:

struct M3DVertex3f {        
    float v[3] __attribute__ ((packed)); // this is a static array, so no double pointers!
    M3DVertex3f &operator=(M3DVertex3f const &src);
}

M3DVertex3f &M3DVertex3f::operator=(M3DVertex3f const &src)
{
    for(int i=0;i<3;i++)
         v[i] = src.v[i];       
    return *this;        
}

std::vector<M3DVertex3f> Verts;