引用到全局数组时更改了 C++ 数组内容
c++ array content changed when refereing to global array
我试图使用 openGl 编写 c++ 代码来渲染Sierpinski_gasket。我已经使用 typedef
定义了拖曳新数据类型,然后我创建了一个指向这些新数据类型之一的指针:
typedef GLfloat point2[2];
typedef point2 myTriangle[3];
myTriangle *triangle;
我编写了一个函数init
,它取三个点,然后创建一个新myTriangle
,然后将其分配给*triangle
void init(point2 p1, point2 p2, point2 p3){
myTriangle t;
t[0][0] = p1[0];
t[0][1] = p1[1];
t[1][0] = p2[0];
t[1][1] = p2[1];
t[2][0] = p3[0];
t[2][1] = p3[1];
triangle = &t;
}
这是我diplay
函数:
void display(void){
static point2 p = {1,1};
int i;
//pick a random vertex
i = rand() % 3; //i in the range 0 to 2
p[0] = (p[0] + *triangle[i][0])/2;
p[1] = (p[1] + *triangle[i][1])/2;
cout << p[0] << ' , ' << p[1] << endl;
//display new points
glBegin(GL_POINTS);
glVertex2fv(p);
glEnd();
}
问题是每次调用*triangle
后display
的值都会发生变化。谁能告诉我为什么以及如何解决这个问题?
完整代码如下
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <cstdlib>
#include <iostream>
using namespace std;
typedef GLfloat point2[2];
typedef point2 myTriangle[3];
myTriangle *triangle;
void init(point2 p1, point2 p2, point2 p3);
void display(void);
int main(int argc, char** argv) {
//initialize the GLUT library
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL");
//openGL Code
glClearColor(0.0, 1.0, 0.0, 0.0 );
glClear(GL_COLOR_BUFFER_BIT);
glOrtho(-5.0, 15.0, -5, 15.0, -1.0, 1.0);
glColor3f(1.0, 0.0, 0.0);
glEnable(GL_POINT_SMOOTH);
glPointSize(5);
//triangle points
point2 p1, p2, p3;
p1[0] = 5.0;
p1[1] = 0.0;
p2[0] = 10.0;
p2[1] = 0.0;
p3[0] = 7.5;
p3[1] = 10.0;
init(p1,p2,p3);
// glBegin(GL_TRIANGLES);
// glVertex2fv(p1);
// glVertex2fv(p2);
// glVertex2fv(p3);
// glEnd();
for(int j=0 ; j< 10000; j++){
display();
}
glFlush();
glutSwapBuffers();
glutMainLoop();
return 0;
}
void init(point2 p1, point2 p2, point2 p3){
myTriangle t;
t[0][0] = p1[0];
t[0][1] = p1[1];
t[1][0] = p2[0];
t[1][1] = p2[1];
t[2][0] = p3[0];
t[2][1] = p3[1];
triangle = &t;
}
void display(void){
static point2 p = {1,1};
int i;
//pick a random vertex
i = rand() % 3; //i in the range 0 to 2
p[0] = (p[0] + *triangle[i][0])/2;
p[1] = (p[1] + *triangle[i][1])/2;
cout << p[0] << ' , ' << p[1] << endl;
//display new points
glBegin(GL_POINTS);
glVertex2fv(p);
glEnd();
}
void init(point2 p1, point2 p2, point2 p3){
myTriangle t;
..
triangle = &t;
} // Life time of 't' ends here.
问题是triangle
引用了导致未定义行为的局部变量。
您正在init
函数中分配局部变量的地址。 当init
返回时,您分配的地址不再有效,因为与该地址绑定的变量是本地变量。
void init(point2 p1, point2 p2, point2 p3)
{
myTriangle t;
t[0][0] = p1[0];
t[0][1] = p1[1];
t[1][0] = p2[0];
t[1][1] = p2[1];
t[2][0] = p3[0];
t[2][1] = p3[1];
triangle = &t; // <-- assigning address of local variable. No good.
}
代码的问题在于,您没有一个活动myTriangle
可供您分配给triangle
指针。
您当前的代码triangle
设置为一个myTriangle
,一旦init
函数返回,该就会消失,并且代码中的任何内容都表明triangle
将指向的这个"活动"对象将存在在哪里。
所以实际上,你要求一个只有你能真正想出的解决方案。 我们可以建议一些事情,比如分配一个全局myTriangle
,地址不会失效,或者在函数中使用new myTriangle
来动态分配一个地址(这会导致其他问题),或者其他类似的答案。 但是,这是您必须做出的设计决策。
typedef GLfloat point2[2];
typedef GLfloat myTriangle[3][2]; // EDIT
myTriangle *triangle;
编译和运行正常,应该做你想做的事。
除了马赫什的回答,*triangle[i][0]
可能没有做你想做的事。相当于*(triangle[i][0])
.由于triangle
指向单个三角形,因此如果i > 0
,则为UB。你需要做(*triangle)[i][0]
。这将首先取消引用指针。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '