Странный сбой с помощью pointers / malloc () при проверке значения указателя - PullRequest
0 голосов
/ 22 января 2010

У меня тут действительно странный сбой, я уже получил его раньше, но я подумал, что исправил это, добавив = NULL к объявлениям переменных:

#include <stdlib.h>

...

GLuint *TEX = NULL;
int TEX_MEMSIZE = sizeof(GLuint)*1024*1024;

...

void something1(){
    ...
    TEX = (GLuint *)malloc(TEX_MEMSIZE);
    ...
}

void something2(){
    ...
    // this line runs fine.
    if(TEX != NULL){ // CRASH ON THIS LINE OF CODE
        // wont run anything after the above line.
        free(TEX);
    }
    // ...nor here since it crashed...
    ...
}

Он падает на моем ноутбуке / Vista, но не на моем настольном компьютере / WinXP.

Когда я удаляю это, если check и free (), он больше не падает.

Я просто не понимаю, что я делаю не так? Что может вызвать это? я только знаю, что неправильно предопределенные массивы могут вызвать некоторые нелогичные ошибки, я не верю, что сейчас в моем коде есть такие неправильные массивы, так что я жду новых идей. (и потому что проверка 20 тысяч строк кода тоже может быть довольно медленной)

Редактировать: Теперь я заметил, что он не вылетит до free (), но ПОСЛЕ этого. Я начинаю думать, что это какая-то предопределенная проблема с массивами ... так как положение сбоя меняется. (или у меня просто слабоумие).

РЕДАКТИРОВАТЬ 2: ИСПРАВЛЕНО, было два вызова free (), до и после malloc ()> _> Теперь я чувствую себя настолько глупо.

Ответы [ 8 ]

2 голосов
/ 22 января 2010
free(TEX);

освобождает память, но не меняет указатель. Измените его на

if (TEX != NULL)
{
    free(TEX);
    TEX = NULL;
}

Так что если вы вызываете что-то2 () во второй раз, он не будет пытаться освободить (TEX) снова.

1 голос
/ 22 января 2010

Как определяется TEX_MEMSIZE ?

Это должно быть что-то вроде:

#define NUM_ENTRIES 50
#define TEX_MEMSIZE NUM_ENTRIES * sizeof(GLuint)
0 голосов
/ 23 января 2010

Проблема не в самом свободном. Ваша ошибка заключается в коде, который не указан в этом посте, так как вы должны перезаписать память выше выделенной области Если в free () происходит сбой, это происходит в основном из-за 2 вещей:

  • вы передали неправильный указатель (не выделен с помощью malloc ())
  • вы перезаписали память до или после выделенного блока

Я почти уверен, что нет. 2 будет вашей проблемой в этом случае.

0 голосов
/ 22 января 2010

Исходя из вашего обновления вопроса, где происходит сбой не проверки NULL, а вызова free ():

Что-то в вашей программе повреждает либо инфраструктуру кучи, либо фактическое значение TEX.

0 голосов
/ 22 января 2010

Мой хрустальный шар говорит, что тебе нужно сделать

#include <stdlib.h>

во всех исходных файлах, где вы используете malloc(), realloc() и free(). Если это не решит вашу проблему, вы должны опубликовать минимально компилируемый код, демонстрирующий такое поведение.

Если это действительно решит вашу проблему: пропущенный #include <stdlib.h> означает, что malloc() не имеет прототипа в области видимости. Компилятор предполагает, что он возвращает int. Это не, конечно. Обычно компилятор предупреждает вас, когда вы присваиваете результат malloc() типу указателя, но из-за приведения компилятор предполагает, что вы знаете, что делаете, и не предупреждает вас. По этой причине я не рекомендую приводить возвращаемое значение malloc() в C.

Итак, ваш malloc() вызов будет:

#include <stdlib.h>
TEX = malloc(TEX_MEMSIZE);

Кроме того, вы предполагаете, что sizeof(int) делит TEX_MEMSIZE. Вы хотите TEX_MEMSIZE байтов или TEX_MEMSIZE int с? Если последнее, вам нужно умножить на sizeof(int) в вашем malloc() вызове:

TEX = malloc(TEX_MEMSIZE * sizeof *TEX);

Вам также следует изменить тип TEX_MEMSIZE. В C int гарантированно хранит только значения <= 32767. Может быть в состоянии хранить большие значения, но это не точно. Поскольку вы используете его для <code>malloc(), я бы порекомендовал тип size_t или, что еще лучше, сделайте его #define.

Исходя из ваших правок, вы можете изменить TEX после malloc(), а затем передать это значение free(). Вы уверены, что TEX не изменяется между malloc() и free()?

0 голосов
/ 22 января 2010

повторите один и тот же тест TEX! = NULL повсюду, сразу после malloc все будет в порядке; это конечно сломано позже.

Продолжайте повторять тест во всем коде «...». В конце концов вы обнаружите, что есть место, где оно работало до строки x, но не после нее. Это укажет пальцем на проблему

Или ваши символы отладки неверны, и сбой не происходит там, где вы думаете. Закройте VS, снова откройте, перестройте все и попробуйте снова

0 голосов
/ 22 января 2010

Предполагая, что TEX действительно является типом указателя (имеется в виду, что вы не объявляете его повторно в более локальной области видимости), единственный способ, которым строка

if (TEX! = NULL) {

Может произойти сбой, если доступ к TEX вызвал недопустимый доступ к памяти. Поскольку TEX является глобальной переменной, единственный способ, которым она может быть при недопустимой памяти, - это если библиотека DLL, которая определяет TEX, не загружена в процесс. Поместите точку останова перед оператором IF и убедитесь, что DLL, содержащая объявление TEX, загружено в процесс.

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

сон (60 *1000* X);

перед оператором IF и используйте служебную программу «Обозреватель процессов» Windows Internals (теперь распространяется Microsoft), чтобы увидеть, какие модули загружены в процессе. Установите «X» на количество минут, которое вам потребуется, 2 или 3 должно быть достаточно.

0 голосов
/ 22 января 2010

Исходя из заданных данных и предполагая, что программа является многопоточной, может возникнуть условие гонки между проверкой if (TEX! = NULL) и свободной, что может привести к освобождению указателя NULL. Вы можете проверить это.

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