为什么这不起作用?

时间:2010-05-25 00:43:38

标签: c++ c malloc

我试图通过创建一个全局变量来解决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用于函数中创建的指针与全局变量有什么不同?

由于

3 个答案:

答案 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 ...从头顶看它(它已经晚了我的睡觉时间......