#include<stdio.h>
int main()
{
char *str;
gets(str);
puts(str);
return 0;
}
выход = Сегментация FaultКак указатели выделить память
Почему он дает ошибку сегментации?
#include<stdio.h>
int main()
{
char *str;
gets(str);
puts(str);
return 0;
}
выход = Сегментация FaultКак указатели выделить память
Почему он дает ошибку сегментации?
В случае
gets(str);
str
используется неинициализированным. Будучи автоматической локальной varibale, если явно не инициализировано, содержимое str
является неопределенным. Он может указывать на место памяти, которое не выделяется вашей программе.
Использование (попытки записать или даже читать с) Непознанная память вызывает undefined behavior. Ошибка сегментации является одним из побочных эффектов.
Тем не менее, gets()
является чистое зло, из-за возможных проблем переполнения буфера. Вместо этого используйте fgets()
.
Ответ на вопрос «как указатели выделяют память» очень прост: они этого не делают. Вот почему вы получаете ошибку сегментации: доступ к данным из неинициализированного указателя равен неопределенное поведение.
Это программист, которому приходится выделять память и назначать ее указателю. Например, вы могли бы использовать malloc
:
char *str = malloc(10);
fgets(str, 10, stdin);
puts(str);
Важная вещь, чтобы отметить о приведенном выше затруднительного является то, что fgets
используется вместо устаревшей gets
. Это связано с тем, что fgets
позволяет рассказать функции, сколько памяти она может использовать в вашем буфере, а gets
предполагает, что у нее есть вся необходимая память, что приводит к переполнению буфера.
спасибо, сэр! ваше предложение очень помогло ...... –
@ShubhamTiwari Добро пожаловать. Если это ответит на ваш вопрос, подумайте о принятии ответа, нажав на серый флажок рядом с ним. Это позволит другим посетителям сайта узнать, что ваша проблема решена, и заработайте значок на переполнении стека. – dasblinkenlight
Необходимо перенести первую страницу. Как это:
#include <stdio.h>
int main()
{
char *str;
str = malloc(4096);
gets(str);
puts(str);
free(str);
return (0);
}
Это позволит писать на ул.
Для лучшего распределения памяти может быть хорошей идеей узнать, сколько памяти вам нужно, а не произвольное «4096».
Кроме того, не забудьте использовать бесплатный(), когда он вам больше не нужен.
Когда вы объявляете указатель, все, что вы сделали, зарезервировано для хранения адреса другого объекта; вы не выделили места для этого другого объекта.
Вот гипотетическая карта памяти (адреса вытягивают из воздуха и не представляют каких-либо реальных слов архитектуры, предположим, 32-разрядные слова):
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
str 0xfff86400 ?? ?? ?? ?? // ?? represents unknown byte value
переменнаяstr
находится по адресу 0xfff86400
.Так как вы объявили str
с auto
продолжительности хранения (то есть, в пределах функции) и не явно инициализировать его, его значение неопределенными; он содержит неизвестный бит-шаблон, который (скорее всего) не соответствует записываемому адресу в вашей программе. gets
пытается записать данные недействительный адрес, следовательно segfault . Ни один из входных процедур (fgets
, scanf
, fscanf
, fread
и т.д.) не будет выделять память для хранения фактического ввода; это ваша ответственность.
Если вы хотите что-то манипулировать с помощью указателя, вам нужно выделить предмет, указатель которого указывает на. Например, вы могли бы сделать что-то вроде этого:
char buf[8] = "blah!";
char *str = buf;
Это выделяет буфер для хранения до 8 символов, а затем присваивает адрес первого элемента этого буфера str
, что дает нам что-то вроде этого:
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
buffer 0xfff86400 'b' 'l' 'a' 'h'
0xfff86404 '!' 00 ?? ??
str 0xfff86408 ff f8 64 00
Кроме того, вы можете использовать malloc
для динамического выделения памяти для str
, чтобы указать:
char *str = malloc(BUF_SIZE);
malloc
резервирует BUF_SIZE
байт для хранения строки ввода и присваивает указатель на это пространство для str
.
Указатели не выделяют память. – juanchopanza
Если вы хотите выделить память, вам нужно вызвать 'malloc()' – Barmar
'str' - это просто указатель. В какой области памяти указывается 'str'? Не знаете? Я тоже, потому что вы его не инициализировали. Он мог указывать куда угодно. На самом деле вам повезло, что он разбился. – cdarke