0

Я имею ниже фрагмент кода, который выделяет память из границ:таНос Выделяет Из Bound памяти Адрес

char *str1 = (char *) malloc(sizeof(char) * BUF_SIZE); 
printf ("str1 = "); 
scanf("%s", &str1); 
int n = strlen(str1); 

Изначально я получал Segmentation Fault в strlen(). После игры с gdb я узнал, что str1 был на адресе, который был вне пределов. Ниже показан вывод gdb.

(gdb) print str1 
$1 = 0x636261 <Address 0x636261 out of bounds> 

Примечание: Точка прерывания был установлен на линии, где strlen() называется. Также BUF_SIZE: #define BUF_SIZE 10

Любая помощь была бы принята с благодарностью. Спасибо :)

+0

Добавить 'memset (str, 0, BUFSIZE)' перед 'чтением' в него – ForceBru

+0

Вместо этого использовать 'scanf' использовать' fscanf' или 'fgets'. – Algo

+0

@ Алго: Почему? Обычно я советую против '* scanf()' самостоятельно, но в этом случае это вряд ли проблема, особенно если предположить, что вместо нее используется 'fscanf()', которая имеет те же проблемы, что и 'scanf()' ...? – DevSolar

ответ

8

Вы должны пройти str1, а не &str1, до scanf().

scanf() ожидает char * для формата "%s"; вы передаете адрес char *. Это не приводит к счастью.

Поскольку BUF_SIZE настолько мал - всего 10, вы говорите - вам нужно использовать:

if (scanf("%9s", str1) != 1) 
    …process error or EOF… 

Это защитит вас от переполнения буфера. Вы должны указывать размер каждый раз, когда используете %s (если вы не используете модификатор POSIX %ms до scanf(), но тогда все правила меняются). Если вы этого не сделаете, scanf() может писать за пределами вашей строковой переменной, не зная.

Вы также должны проверить, что malloc() преуспевает. Всегда. Каждый раз.

+1

Обратите внимание, что компиляция с помощью GCC и '-Wall' (или' -Wformat') укажет на ошибку ваших путей. Если вы используете GCC, вы всегда должны компилировать с помощью '-Wall' (и предпочтительно' -Wextra' тоже - я использую больше опций, чем это), чтобы получить лучшую отчетность об ошибках. (Для файла с вашим кодом в нем GCC сказал: 'warning: format '% s' ожидает аргумент типа 'char *', но аргумент 2 имеет тип 'char **' [-Wformat =]' - or 'error 'при компиляции с '-Werror' тоже.) –

4

У вас есть несколько проблем в вашем коде:

  1. Не читать строку над указатель, вы имели в виду scanf("%s", str1);, падение &!
  2. Don't cast the return value of malloc() in C.
  3. Не предполагайте, что распределения успешны.
  4. Не используйте для этого scanf(), это очень опасно, так как вы не передаете ему никакой информации о доступном размере буфера. Лучше использовать fgets().
+0

К 3-му пункту вы имеете в виду, что я должен проверить, что указатель, возвращаемый из malloc, не является NULL? И в отношении 1-го пункта это было плохо.Отладчики не могут помочь в этом :) –

+0

Было здорово узнать второй пункт также, что он автоматически продвигает void *. –

+0

@sidkamaria Да, вы должны проверить, что возвращаемый указатель не является 'NULL', прежде чем считать, что это не так. – unwind

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