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

Pointer to an array, what am i missing?

本文关键字:什么 指针 数组      更新时间:2023-10-16

我对OpenGL比较陌生,一直在使用它提供的GLTools库。其中一个类GLTriangleBatch在一定程度上处理了一批vertex。该类有一个全局属性指针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?我错过了什么?

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

C中的数组是一组由系统内存支持的连续地址空间。内容由一个基指针和相对于该基指针的偏移量通过一种称为指针算术的机制来寻址。

假设pT类型的指针,用C语法写成T *p。现在让p指向T类型的n元素的一些连续存储器,这些元素被分配为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将其称为向量,以将其与普通数组区分开来;这一开始听起来可能很奇怪,但一旦您从高等数学的角度理解了向量空间,它实际上就有意义了)。您应该能够在向量元素(即Verts[nNumVerts] = verts[iVertex])上使用赋值运算符=,而不是memcpy(...)。如果编译器抱怨,则重载赋值运算符:

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;

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

相关文章: