Почему это не работает? - PullRequest
3 голосов
/ 25 мая 2010

Я пытался устранить утечку памяти в обратном вызове 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 ]

2 голосов
/ 25 мая 2010

Вы выделяете данные только один раз - но GLUtesselator требует более одного набора данных одновременно!

То, что вы здесь делаете, это помещает все данные вершин в одно место в памяти, где в исходном коде у вас было памяти на вершину. Для правильной работы GLUtesselator требуется более одной вершины.

Вы делаете звоните

void gluDeleteTess(GLUtesselator *tessobj);

... потом, ты?

1 голос
/ 25 мая 2010

Скорее всего, причина в том, что что-то за пределами вашего обратного вызова удерживает возвращенные данные через вызовы методcellCallback (), и последующие вызовы для метода63Cackback () блокируют данные более старых вызовов.

0 голосов
/ 25 мая 2010

Глядя на код, вам нужно переписать это, есть несколько неправильных вещей, которые показывают присущее отсутствие понимания указателей и использование параметра вызова по ссылке, такого как dataOut, во-вторых, проверка вызова не выполняется на malloc, что может привести к сбою и WILL , код слепо предполагает, что память доступна, в-третьих, у вас есть избыточные переменные указателя, такие как vertex и gluptr по причине. Вы на самом деле пытаетесь создать блок памяти, копируя содержимое из gluptr в vertex, и используете указатель на блок coords типа данных 'GLDouble', а затем создаете vertex блок памяти ... и, наконец, присвоить его обратно dataOut ... простите, если я неправильно понял, но читать дальше ...

Это код, который удалил избыточные переменные, как показано ниже, и исправляет отсутствие проверки на нулевой указатель ...

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];
       }
    }
}

Последний параметр при вызове этой функции combineCallback - это параметр вызова по ссылке, поэтому используется двойная звездочка.

Я должен спросить это, действительно ли dataOut является фиксированным размером 6 элементов? если это так, то параметр нужно будет настроить ... чтобы он выглядел как *(*dataOut[6]) ... глядя на него сверху моей головы ( уже поздно и я уже не сплю ... )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...