2010-05-25 4 views
3

I'v пытались решить утечку памяти в функции обратного вызова 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; 


} 

в основном вместо того, чтобы делать таНос каждый раз в цикле (таким образом, утечка памяти) im используя глобальный указатель, но это не работает (рисование на экране не работает), что означает, что dataOut не получает данные вершин, на которые указывает мой указатель. Почему использование malloc для указателя, созданного в этой функции, работает иначе, чем глобальная переменная?

Благодаря

+0

* «Это не так 't work "* не является полезным описанием - что не работает? –

+0

в основном, зачем рисовать раньше, но не больше? – jmasterx

+0

Почему здесь есть актерский состав? 'vertex = (GLdouble *) gluptr;'? – kibibu

ответ

2

Вы распределяющие данные только один раз - но GLUtesselator необходим более чем один набор данных, в то время!

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

Вы сделать вызов

void gluDeleteTess(GLUtesselator *tessobj); 

... после этого, не так ли?

+0

так как это можно сделать без утечки? – jmasterx

+0

GLUtesselator, если он написан правильно, должен освободить память, когда он закончит с ней (или вернуть его вам как-то для освобождения). Это основная директива при прохождении вокруг указателей - кто бы ни «владел» указателем, несет ответственность за его освобождение. – paxdiablo

+0

@paxdiablo, вы избили меня до этого: P –

1

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

0

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

Это код, который устранил избыточные переменные, как показано ниже, и фиксирует на отсутствие проверки указателя 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]; 
     } 
    } 
} 

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

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

Смежные вопросы