C. Использование большего количества памяти, чем выделено в malloc - могу ли я вернуть sth, end программу вместо того, чтобы дать ей сбой? - PullRequest
0 голосов
/ 26 августа 2018

Моя программа аварийно завершает работу, когда malloc(x*sizeof(char)), x <предел <code>fgets, несмотря на проверку buffer == NULL.

В моем примере, когда x равен 1, и предел того, что fgets может принять, равен100, и типы пользователей, например.5 символов с клавиатуры (вызов fgets ()), сбой программы, возвращая случайное значение, подобное: 19284791298 значению.

Моя проблема: вместо сбоя я бы предпочел, чтобы он возвращал NULL.

Причина: Я загружаю свой код на Linux-платформу Univ, которая проверяет реакцию программы на изменение предела кучи до 0 и до 130, когда моя программа написана так, что она возвращает NULL, если ввод пользователя превышает 100 символов.Я не совсем понимаю, как среда изменяет лимит памяти на 0 и 130 и что именно меняется, но даже при том, что я заметил, что моя программа в CodeBlocks, windows 10, вылетает в описанной здесь ситуации (x <ввод stdin), несмотря на проверку<code>buffer == NULL.

Я бы хотел, чтобы проверка buffer == NULL могла как-то сработать и предотвратить сбой.

Если x было 100, а size было 1 (вместо 1 и 100), моя программа возвратила бы NULL и установила бы err_code равным 1.

Я думаю: я не могу сделать с x то же самое выражение "if", которое я сделал для strlen (buffer), потому что ... чтобы проверитьКак долго вводится в буфер, во-первых, мне нужно проверить длину того, что было записано в этот буфер?!.

printf("Insert data: ");
char *buffer = (char* )malloc(1*sizeof(char));
if (buffer == NULL) 
    return NULL;

int size=100;
if (fgets(buffer, size, stdin)!=NULL) {
    if (strlen(buffer)>(unsigned)(size-2)) { //'\0' and enter are 2 chars
        free(buffer);
        *err_code=1;
        return NULL;
    }
//... here goes some sscanf to fill struct fields, etc.
}

Другими словами.Немного сжато то, что, я думаю, может привести к пониманию моей проблемы:

  1. Есть ли способ завершить программу, возвращающую что-то, вместо того, чтобы позволить ей аварийно завершить работу в такой ситуации?Способ заставить if(buffer == NULL) работать?Почему эта проверка не работает?

  2. Я не знаком с Linux.Когда я вижу комментарий в отчете, который я получаю, что linux устанавливает (куча?) Ограничение на 0 или 130 (при тестировании моей программы), означает ли это, что я могу воспроизвести проблемы, с которыми он сталкивается, установив для x значение 0,130?(в части malloc(x*sizeof(char)).

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

В вашем коде вы выделили буфер в виде одного байтового массива

char *buffer = (char* )malloc(1*sizeof(char));


int size=100;
if (fgets(buffer, size, stdin)!=NULL) {

В fgets вы хотите прочитать в буфер ввод 100 байтов.Когда входные данные считываются в буфер, они выходят за пределы выделенной области и перезаписывают другие данные.Из-за этого ваша программа падает,

0 голосов
/ 26 августа 2018

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

Поэтому, когда вы говорите

char *buffer = (char* )malloc(1*sizeof(char));

, за которым следует

int size=100;
fgets(buffer, size, stdin)

, вы солгали.Вы выделили буфер размером 1 и сказали fgets, что размер буфера равен 100. Таким образом, fgets будет считывать до 99 символов и сохранять их в buf, и в большинстве случаев это будет плохопереполнить буфер.

То, что вы хотите сделать, выглядит примерно так:

int size = 100;
char *buffer = (char* )malloc(size*sizeof(char));
if (buffer == NULL) 
    return NULL;

if (fgets(buffer, size, stdin)!=NULL) {
    ...

Кроме того, хотя это не имеет никакого отношения к вашей проблеме, нет необходимостиумножьте на sizeof(char) при вызове malloc, и в C нет необходимости приводить возвращение из malloc в тип указателя назначения.Я бы просто позвонил

char *buffer = malloc(size);
...