指向数组的指针,我缺少什么
Pointer to an array, what am i missing?
我对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中的数组是一组由系统内存支持的连续地址空间。内容由一个基指针和相对于该基指针的偏移量通过一种称为指针算术的机制来寻址。
假设p
是T
类型的指针,用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++中的数组不携带任何内部大小信息,因此无法检查"数组对象",只能查看指定地址的内存中的内容。
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 初始化或分配空字符串文字到指向 C 中的 char 的指针或指向 C++ 中 const char 的指针的原因是什么
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 使用基类指针调用基类的值构造函数的语法是什么?
- 将指针分配给另一个指针时会发生什么情况?
- 当该数组的索引中没有元素时,指针指向什么?
- C++:Lambda 函数指针转换的用例是什么?
- C++关于指针和使用函数将它们启动到堆的行为究竟是什么?
- 这个失败的测试是将零添加到空指针未定义的行为、编译器错误还是其他什么?
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- 什么是更好的做法?通过指针或标识符传递类成员?
- 如果我在 const 函数上使用指针,我可以返回什么?
- 为什么此指针值不能转换为整数的规则是什么?
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 在什么情况下,需要共享智能指针而无法使用唯一指针?
- 以下与指针相关的代码的输出是什么?
- 指向数组基址的指针而不是指向第一个元素的指针有什么优点?
- C++:在向量中插入什么 - 指针或引用,矢量何时复制它的元素?