我试图通过创建一个全局变量来解决GLU回调中的内存泄漏,但现在它不会绘制任何东西:
GLdouble *gluptr = NULL;
void CALLBACK combineCallback(GLdouble coords[3], GLdouble *vertex_data[4],
GLfloat weight[4], GLdouble **dataOut)
{
GLdouble *vertex;
if(gluptr == NULL)
{
gluptr = (GLdouble *) malloc(6 * sizeof(GLdouble));
}
vertex = (GLdouble*)gluptr;
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
for (int i = 3; i < 6; i++)
{
vertex[i] = weight[0] * vertex_data[0][i] +
weight[1] * vertex_data[0][i] +
weight[2] * vertex_data[0][i] +
weight[3] * vertex_data[0][i];
}
*dataOut = vertex;
}
基本上不是每次在循环中使用malloc(因此内存泄漏)使用全局指针,但这不起作用(绘制到屏幕不工作),这意味着dataOut没有接收指向的顶点数据通过我的指针。为什么将malloc用于函数中创建的指针与全局变量有什么不同?
由于
答案 0 :(得分:2)
您只分配一次数据 - 但GLUtesselator一次只需要一组数据!
你在这里做的是将所有顶点数据放在内存中的单个位置,在原始代码中,每个顶点都有内存。 GLUtesselator需要多个顶点才能正常运行。
您执行致电
void gluDeleteTess(GLUtesselator *tessobj);
...之后,你呢?
答案 1 :(得分:1)
最有可能的原因是,回调之外的东西会在对combineCallback()的调用中保留返回的数据,而后来对combineCallback()的调用现在来自旧调用的数据。
答案 2 :(得分:0)
查看代码,你需要重写它,有一些错误,它表明固有缺乏理解指针和使用call {by-reference参数,如dataOut
,其次,没有检查对malloc
的调用可能失败且 WILL 失败,代码盲目地假定内存可用,第三,您使用了冗余指针变量,例如vertex
和{{ 1}}是有原因的。您实际上是通过将内容从gluptr
复制到gluptr
来构建内存块,并使用vertex
指向数据类型“GLDouble”的块指针,然后建立coords
内存块......最后将其分配回vertex
...如果我误解了,请继续阅读...
这是已删除冗余变量的代码,如下所示,并修复了缺少检查NULL指针的问题......
GLdouble *gluptr = NULL; void CALLBACK combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut) { if((*dataOut) == NULL) { (*dataOut) = (GLdouble *) malloc(6 * sizeof(GLdouble)); } if (*dataOut != NULL){ /* PASSED MEMORY ALLOC! */ (*dataOut)[0] = coords[0]; (*dataOut)[1] = coords[1]; (*dataOut)[2] = coords[2]; for (int i = 3; i < 6; i++) { (*dataOut)[i] = weight[0] * vertex_data[0][i] + weight[1] * vertex_data[0][i] + weight[2] * vertex_data[0][i] + weight[3] * vertex_data[0][i]; } } }
调用此函数dataOut
时的最后一个参数是call-by-reference参数,因此使用了双星号..
我必须问一下,combineCallback
肯定是6个元素的固定大小吗?如果是这样的话那么参数需要调整......让它看起来像dataOut
...从头顶看它(它已经晚了我的睡觉时间...... )