2013-09-07 2 views
1

Моя функция заключается в следующем:malloc.c: 3096: SysMalloc: утверждение не удалось

void Insert_ldb(int t){ 
    struct node_ldb *temp_ldb1,*lastnode_ldb; 
    temp_ldb1=root_ldb[t]; 
    while(temp_ldb1->next!=NULL) 
     temp_ldb1=temp_ldb1->next; 
    if(temp_ldb1->next==NULL){ 
     lastnode_ldb=malloc(sizeof(*lastnode_ldb));//error appears at this line 
     temp_ldb1->next=lastnode_ldb; 
    } 
} 

и структура node_ldb определяется как:

struct node_ldb{ 
    int sno; 
    int *lvar; 
    int *object; 
    struct node_ldb *next; 
}; 

На не компиляции ошибок нет появляется, но на выполнение он заканчивается сообщением:

malloc.c: 3096: sYSMALLOc: Утверждение (old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0) не выполнено. Aborted

Странная деталь заключается в том, что одна и та же функция успешно выполняет много раз до прекращения. Возможно ли, что ошибка произошла где-то в другом месте? Потому что даже valgrind не показывает никакой ошибки для того же самого. В чем может быть проблема?

+2

'temp_ldb1 = root_ldb [t];' Есть ли гарантия, что этот указатель никогда не будет NULL (или недействителен)? – wildplasser

+0

@wildplasser Спасибо за исправление. Я думал, что '* lastnode_ldb' вызывает разыменование, что не так. – Mahesh

+0

Нет, sizeof is _mostly_ оператор времени компиляции. Для ВЛА есть разные отличия. BTW (для OP) есть ли VLA? Добавьте определение структуры к вопросу. – wildplasser

ответ

3

Это интенсивно пахнет коррупцией управления памятью, произошедшей до этого звонка до malloc().

Поврежденные данные управления памятью затем совершили этот вызов до malloc().

Я настоятельно рекомендую запустить программу с помощью контролера памяти, например, Valgrind до тех пор, пока не будет воспроизведена неисправность.

+0

Проблема заключалась в том, что раньше я выделял память. Я фактически присваивал памяти размеру (структуре) указателю (для структуры), тогда как я должен был назначить размер (struct *). Благодаря.. – ceedee

1

Память развращается. Вы можете попробовать несколько простых вещей.

1) Поставьте счетчик в Insert_ldb. Надеемся, что программа выйдет из строя с одинаковым значением счетчика. Если это так, это может облегчить отладку.

2) Добавьте несколько байтов заполнения в malloc, например. начиная с 8 байтов.

3) Как правило, рекомендуется инициализировать содержимое после получения памяти с помощью malloc.

#define PAD_BYTES  8 

void Insert_ldv(int t) 
{ 
    static int counter; 
    struct node_ldb *temp_ldb1, *lastnode_ldb; 

    counter++; 
    printf("counter = %d\n", counter); 

    temp_ldb1 = root_ldb[t]; 
    while (temp_ldb1->next != NULL) { 
     temp_ldb1 = temp_ldb1->next; 
    }        

    if (temp_ldb1->next == NULL){ 
     lastnode_ldb = malloc(sizeof(*lastnode_ldb) + PAD_BYTES); 
     memset(lastnode_ldb, 0, sizeof(*lastnode_ldb)); 
     temp_ldb1->next = lastnode_ldb; 
    }         
} 

Когда программа не работает с заполнением, у вас есть обходной путь на короткий срок. Увеличьте PAD_BYTES кратным 4 до тех пор, пока он не завершится. При работе отлично, PAD_BYTES - это количество байтов, которое переполняет память.

Как установить лор и объект? Я предполагаю, что у объекта, вероятно, больше элементов данных, чем выделенная память, и, как следствие, это переписывание и развращение кучи.

Кроме того, когда память освобождается?

1

Это, скорее всего, указывает на повреждение кучи.

Есть некоторые странные вещи об этой функции. Например, next, поданный новым узлом, остается неинициализированным. Зачем? (Даже не говоря уже о остальных полях.)

Также temp_ldb1->next==NULL проверка в if выглядит чрезмерным, так как предыдущий while цикл гарантирует, что уже равна нулю в этой точке.

P.S. Авторы этого sYSMALLOc использовали довольно плохую практику программирования написания сверхкомплексных условий утверждения.Теперь мы не можем понять, какое конкретное под-условие не удалось.