2017-02-14 5 views
0

При освобождении некоторых указателей я получаю нарушение доступа.
Чтобы узнать, что происходит, я решил попросить освободить указатели на более ранней стадии кода даже после того, как выделена память, и все равно она выйдет из строя.
Это означает, что что-то серьезно ошибочно в том, как мои структуры обрабатываются в памяти.Почему исключение нарушения доступа при освобождении сразу после выделения памяти

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

Кто-нибудь знает, что не так в этом фрагменте кода или каково должно быть указанное ключевое слово?

typedef unsigned long longword; 
typedef struct part_tag { struct part_tag *next; 
           __int64 fileptr; 
           word needcount; 
           byte loadflag,lock; 
           byte partdat[8192]; 
           } part; 

static longword *partptrs; 

<keyword> part *freepart; 
<keyword> part *firstpart; 

void alloc_parts (void) { 
    part *ps; 
    int i; 

    partptrs = (longword*)malloc (number_of_parts * sizeof(longword)); // number... = 50 
    ps = (part*)&freepart; 

    for (i=0; i<number_of_parts; i++) { 
    ps->next = (struct part_tag*)malloc(sizeof(part)); 
    partptrs[i] = (longword)ps->next; 
    ps = ps->next; 
    ps->fileptr = 0; ps->loadflag = 0; ps->lock = 0; ps->needcount = 0; // fill in "ps" structure 
    }; 
    ps->next = nil; 
    firstpart = nil; 
    for (i=0; i<number_of_parts; i++) { 
    ps = (part*)partptrs[i]; 
    free(ps); <-- here it already crashes at the first occurence (i=0) 
    }; 

} 

Заранее спасибо

В комментариях кто-то спрашивает, почему я освободив указатели непосредственно после их распределения. Это не то, как была изначально написана программа, но для того, чтобы узнать, что вызывает нарушение прав доступа, я переписал этот стиль.
Первоначально:

alloc_parts(); 
<do the whole processing> 
free_parts(); 

Для анализа нарушения доступа я приспособил alloc_parts() функции в исходном фрагменте кода я написал там. Дело в том, что даже сразу после выделения памяти освобождение идет не так. Как это вообще возможно?

В то же время я наблюдал еще одно странное явление:
При распределении памяти значения ps кажутся «полными» значениями адреса. При попытке освободить память значения ps содержат только последние цифры адресов памяти.

Example of complete address :  0x00000216eeed6150 
Example of address in freeing loop : 0x00000000eeed6150 // terminating digits are equal, 
                 // so at least something is right :-) 

Эта проблема была вызвана longword типа: кажется, что этот тип был слишком мал, чтобы держать целые адреса памяти. Я заменил его другим типом (unsigned long long), но проблема все еще сохраняется.

+0

Что такое 'longword'? Пожалуйста, отправьте * полный * пример. (Http://stackoverflow.com/help/mcve) –

+0

Что такое 'longword'? Почему вы выделяете байты 'number_of_parts * longwords' вместо, например, 'number_of_parts * sizeof (part)'? И что самое главное, почему вы используете '& freepart', который даст вам указатель * на указатель *? –

+1

Это очень плохой код, он рассматривает указатели как целые числа.Если у вас разные размеры, вы можете угоститься. Перепишите его без странного бизнеса «лорда». – unwind

ответ

0

Наконец, после долгого времени страданий, проблема решена:

Программа изначально была разработана как 32-битное приложение, которое означает, что исходный тип unsigned long было достаточно, чтобы держать адреса памяти.

Однако эта программа компилируется теперь, как 64-разрядные приложения, поэтому упомянутый тип не является достаточно большим, больше держать адреса памяти 64-разрядные, следовательно, другой тип был использован для решения этой проблемы:

typedef intptr_t longword; 

Это решает проблему.

@Andrew Henle: извините, я не осознал, что ваш комментарий содержит фактическое решение этой проблемы.

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