2013-02-10 1 views
-2

В C, я обнаружил ошибку, когда я закодирован следующий пример:Отрицательное индексирование; дает ошибку при освобождении

int *pointer; 
int i = 0; 
pointer = malloc(10 * sizeof(int)); 
pointer[i - 1] = 4; 

Ясно i является отрицательным индексом в pointer.

Даже если неправильная память детали была изменена, почему ошибка была инициирована только при free(pointer) [позже в коде]? Ошибка: double free or corruption (out).

EDIT: Компилятор использовали gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

+0

Какой компилятор? – asheeshr

+6

Более чем вероятно, член кучи, размер блока и другая информация сохраняются в памяти сразу * до * до возвращаемого адреса из 'malloc()'. Замена этих данных на коррупцию не изменит способность использовать фактический блок. Скорее, когда это необходимо (во время свободного), возникает коррупция и заворачивает свою уродливую голову. Но ** это полностью зависит от реализации **. – WhozCraig

+6

Если вы делаете глупые вещи, ожидайте глупого поведения. В этом случае вы изменяете память, которая не принадлежит вам. Поэтому вы должны ожидать неожиданного. –

ответ

4

Большинство, если не все диспетчеры памяти (например: таНос) выделить дополнительные данные вокруг памяти вы просили. Это лишний раз - помочь менеджеру памяти управлять различными распределениями, добавляя некоторые свои собственные данные в распределение. Когда вы сделали свой отрицательный индекс, вы переписали эти дополнительные данные. Это не недопустимая память сама по себе, поэтому CPU не может защитить ее, но malloc действительно будет жаловаться, когда увидит, что ее данные были обработаны. Это произойдет на free().

+0

["per se":)] (http://en.wiktionary.org/wiki/per_se). В противном случае отличный ответ, +1. – us2012

+0

Thx - редактировать сделано. – PQuinn

+3

Ключевыми работами, отсутствующими в этом ответе, являются: ** Неопределенное поведение (UB) **. Доступ к ячейке памяти, которая не принадлежит вам, - UB. UB произошел, когда доступ к карте памяти был недоступен, что происходит после того, как это было чисто неопределенным. Это может или не может привести к сбою или записи диска. Никакое поведение не гарантируется. –

1

По существу, доступ к pointer[-1], как вы это делали, дает неопределенное поведение; в теории, ничего может случиться. Но на практике есть хорошее объяснение конкретного сообщения об ошибке, которое вы получили.

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

Когда вы перезаписали, что часть памяти, вы оставили внутренности malloc - системы free в неустойчивом состоянии, что приводит free сообщить об ошибке, когда это было обнаружено. Наиболее вероятным временем для такого открытия, конечно, является то, когда функции управления памятью называются об этой области памяти. (Некоторые malloc коррупции будут обнаружены при следующем вызове malloc, но для достижения этого обычно требуется более целенаправленное усилие.) Вызов realloc должен дать вам аналогичное сообщение об ошибке.

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