C malloc с 2D Array: Почему нет ошибки сегментации? - PullRequest
1 голос
/ 12 сентября 2011

Я использую этот метод для выполнения malloc над 2d-массивом, мои источники: http://c -faq.com / aryptr / dynmuldimary.html и Изменение стратегии malloc для 2D Array, чтобы malloc был успешным:

int
main(int argc, char *argv[])
{
    long **array = NULL;

    array = malloc(5 * sizeof(long *));
    for (int i = 0; i < 5; i++)
        array[i] = malloc(3 * sizeof(long));

    array[4][2] = 515;
    array[4][3] = 212;
    array[4][10000] = 3;

    printf("%ld\n", array[4][10000]);

    return 0;
}

Мой вопрос: почему я не получаю ошибку сегментации при выполнении любой из трех последних строк перед возвратом?Насколько это безопасно (игнорируя отсутствие бесплатного)?

Ответы [ 5 ]

6 голосов
/ 12 сентября 2011

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

1 голос
/ 12 сентября 2011

malloc является лишь частью того, как память выделяется процессу.

Операционная система выделяет память целыми страницами, поэтому фрагменты размером 4 КБ или 4 МБ (или другого ...) - большие. Затем процесс в пользовательском пространстве может свободно разбирать эти страницы по своему усмотрению.

malloc выполняет 2 роли:

  • запрос страниц из ОС

  • разбиение этих страниц на выделенные куски

Так что, держу пари, что вы попадаете куда-то на страницу, которой вы владеете, но не в той части, которую вы выделили. Что касается ОС, то все в порядке.

0 голосов
/ 12 сентября 2011

Операционная система выделяет память приложению в страницах (обычно 4 КБ).Для эффективности можно использовать Огромные Страницы (например, 2 МБ)

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

Однако, как только вам была выделена страница, вы можете читать и записывать любую часть этой страницы без ошибки сегментации.(Кодовые страницы обычно защищены от записи)

Когда вы используете malloc, он гарантирует, что нужные вам страницы есть.Однако вы можете просто получить доступ к имеющейся у вас памяти и изменить ее по своему усмотрению.(Предполагая, что вы знали, сколько это было)

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

Примечание: malloc имеет небольшую структуру, например, 8 байт, в начале каждого выделенного блока памяти перед самим блоком, если вы его повредите, то malloc и free не будут работать правильно.

0 голосов
/ 12 сентября 2011

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

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

0 голосов
/ 12 сентября 2011

Запись в память, которой вы не владеете, не обязательно вызывает ошибки сегментации.

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

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