Нет ошибки, даже если я переопределяю предел выделенной памяти? - PullRequest
7 голосов
/ 28 февраля 2010

Я мог бы быть глупым, и вы должны извинить меня в этом случае ... но я не понимаю этого. Я выделяю буфер из 16 символов, а затем (в цикле for) вставляю 23 (!?) случайных символа, а затем распечатываю эти вещи.

То, что я не получаю, это то, как я могу поместить 23 символа в буфер, который malloc'ed как 16 символов ... Когда я изменяю цикл на 24 символа, я получаю сообщение об ошибке (по крайней мере, в Linux с gcc ) ... но почему бы не "раньше" (17 символов должны разбить его ... нет?)

Это мой пример кода:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    char *buf;

    buf = malloc(16 * sizeof(*buf));
    if(buf == NULL) exit(1);

    for(n = 0; n < 22; n++)
    {
        buf[n] = rand()%26+'a';
    }
    buf[n]='\0';

    printf("Random string: %s\n", buf);

    free(buf);
    buf = NULL;

    getchar();
    return 0;
}

Ответы [ 4 ]

6 голосов
/ 28 февраля 2010

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

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

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

3 голосов
/ 28 февраля 2010

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

Конечно, это не то, от чего вы хотите зависеть, это детали реализации библиотеки времени выполнения c и могут быть изменены без предварительного уведомления.

1 голос
/ 28 февраля 2010

Поведение при переполнении буфера в C не определено. Так что может случиться что угодно, в том числе и ничего. В частности, C не требуется и предназначен специально для того, чтобы не выполнять проверку границ.

Если вы получаете какую-либо ошибку во время выполнения, это обычно происходит потому, что она была обнаружена и захвачена операционной системой, а не средой выполнения C. И это произойдет только в том случае, если доступ нарушает память, не сопоставленную с процессом. Чаще всего он просто получает доступ к памяти, принадлежащей вашему процессу, но которая может использоваться другими объектами памяти; поведение вашей программы будет зависеть от того, что ваш код делает с неверными данными.

0 голосов
/ 28 февраля 2010

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

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