Почему я получаю сбой утверждения c malloc?

я реализую полиномиальный алгоритм divide and conquer, поэтому я могу сравнить его с реализацией OpenCL, но я не могу получить malloc на работу. Когда я запускаю программу, она выделяет кучу вещей, проверяет некоторые вещи, а затем отправляет size/2 алгоритму. Затем, когда я ударил malloc строка снова выплевывает это:

Танос.с:3096: sYSMALLOc: утверждение `(old_top == (((mbinptr) (((типа char *) &((АВ)->контейнеры[((1) - 1) * 2])) - __группа builtin_offsetof (struct языка malloc_chunk, ФД)))) && old_size == 0) || ((без знака длинный) (old_size) >= (длинное целое без знака)((((__строение_offsetof (struct языка malloc_chunk, fd_nextsize))+((2 * (оператор sizeof(size_t в))) - 1)) & ~((2 * (оператор sizeof(size_t в))) - 1))) && ((old_top)->размер & 0х1) && ((неподписанных долгое)old_end & pagemask) == 0)' не удалось. Прервано

линия:

int *mult(int size, int *a, int *b) {
    int *out,i, j, *tmp1, *tmp2, *tmp3, *tmpa1, *tmpa2, *tmpb1, *tmpb2,d, *res1, *res2;
    fprintf(stdout, "size: %dn", size);

    out = (int *)malloc(sizeof(int) * size * 2);
}

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

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

7 ответов


99.9% вероятно, что у вас повреждена память (переполненный или неполный буфер, записанный в указатель после его освобождения, вызванный дважды на одном указателе и т. д.)

запустите код в разделе отчет чтобы увидеть, где ваша программа сделала что-то неправильно.


чтобы дать вам лучшее понимание почему это происходит,я хотел бы немного расширить ответ @r-samuel-klatchko.

когда вы называете malloc, что на самом деле происходит немного сложнее, чем просто давая вам кусок памяти, чтобы играть. Под капотом, malloc также сохраняет некоторую домашнюю информацию о памяти, которую он дал вам (самое главное, ее размер), так что при вызове free, Он знает, сколько памяти свободно. Эта информация обычно хранится непосредственно перед местоположением памяти, возвращенным вам malloc. Более исчерпывающую информацию можно найти в интернете™, но (очень) основная идея примерно такова:

+------+-------------------------------------------------+
+ size |                  malloc'd memory                +
+------+-------------------------------------------------+
       ^-- location in pointer returned by malloc

основываясь на этом (и значительно упрощая вещи), когда вы звоните malloc, он должен получить указатель на следующую часть памяти, которая доступна. Один из очень простых способов сделать это-посмотреть на предыдущий бит памяти, который он отдал, и переместить size байт дальше вниз (или вверх) в памяти. С помощью этой реализации вы в конечном итоге ваша память выглядит примерно так после выделения p1, p2 и p3:

+------+----------------+------+--------------------+------+----------+
+ size |                | size |                    | size |          +
+------+----------------+------+--------------------+------+----------+
       ^- p1                   ^- p2                       ^- p3

Итак, что вызывает вашу ошибку?

ну, представьте, что ваш код ошибочно записывает мимо объема памяти, который вы выделили (либо потому, что вы выделили меньше, чем вам нужно, как это было вашей проблемой, либо потому, что вы используете неправильные граничные условия где-то в вашем код.) Скажем, ваш код записывает так много данных в p2 что он начинает перезаписывать то, что находится в p3 ' s


вы, вероятно, переполнены за пределами выделенного mem где-то. тогда базовый sw не поднимет его, пока вы не вызовете malloc

может быть значение охранника clobbered, которое ловится malloc.

правка...добавлено это для проверки границ help

http://www.lrde.epita.fr / ~akim/ccmp/doc/bounds-checking.html


я получил следующее сообщение, похожее на ваше:


    program: malloc.c:2372: sysmalloc: Assertion `(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)' failed.

совершил ошибку при вызове метода раньше, при использовании malloc. Ошибочно переписать знак умножения " * " на " + " при обновлении коэффициента после оператора sizeof()-при добавлении поля в массив беззнаковых символов.

вот код, ответственный за ошибку в моем случае:


    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)+5);
    b[INTBITS]=(some calculation);
    b[BUFSPC]=(some calculation);
    b[BUFOVR]=(some calculation);
    b[BUFMEM]=(some calculation);
    b[MATCHBITS]=(some calculation);

в другом методе позже я снова использовал malloc, и он создал сообщение об ошибке, показанное выше. Вызов было (достаточно просто):


    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)*50);

подумайте, используя знак " + " в 1-м вызове, который приводит к неправильному исчислению в сочетании с немедленной инициализацией массива после (перезапись памяти, которая не была выделена массиву), принесла некоторую путаницу в карту памяти Мэллока. поэтому второй звонок пошел не так.


мы получили эту ошибку, потому что Забыли умножить на sizeof(int). Обратите внимание на аргумент malloc(..)- это количество байтов, а не количество машинных слов или что-то еще.


я портировал одно приложение из Visual C в gcc через Linux, и у меня была такая же проблема с

Танос.c: 3096: sYSMALLOc: утверждение с использованием gcc на UBUNTU 11.

я переместил тот же код в дистрибутив Suse (на другом компьютере), и у меня нет никаких проблем.

Я подозреваю, что проблемы не в наших программах, а в собственном libc.


Я получил ту же проблему, я использовал malloc над n снова в цикле для добавления новых данных char *string. я столкнулся с той же проблемой, но после освобождения выделенной памяти void free() проблема отсортированы