C ++ cin, ошибка сегмента 11 - PullRequest
       4

C ++ cin, ошибка сегмента 11

3 голосов
/ 09 ноября 2011

Это дает мне ошибку сегмента 11 при вводе строки.Почему я получаю ошибку сегмента?Это так просто ... откуда происходит ошибка сегмента?

int main(){
    char * str;
    printf ("please enter string : ");
    cin >> str;
    // reverse_str(str);   
}

Ответы [ 7 ]

5 голосов
/ 09 ноября 2011

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

Решение:
Вы должны использовать std :: string вместо указателя.

std::string str;
std::cout<<"please enter string :  ";
std::cin >>str;

Также старайтесь несмешивать C и C ++.
Использовать streams в C ++ не printf


В качестве альтернативы есть 2 других подхода:

Не очень хороший другой подход 1:
Вы можете выделить память для str, сделав массив фиксированного размера:

#define MAX_INPUT 256
char str[MAX_INPUT]={0};

Недостаток:
Для этого потребуетсязнать длину максимального ввода, который пользователь может ввести во время компиляции, поскольку Массивы переменной длины не разрешены в C ++.

Не так хорошо, другиеПодход 2:
Вы можете динамически выделять память для str, используя new []. str будет указателем в этом случае.

#define MAX_INPUT 256
char *str = new char[MAX_INPUT];

Недостаток:
Опять же, у этого подхода есть недостаток, заключающийся в том, что в этом случае нужно знать, сколько памяти выделить во время компиляции, поскольку пользователь вводит строку.Кроме того, вы должны помнить, чтобы освободить место, позвонив по номеру delete[], иначе у вас утечка памяти.Кроме того, постарайтесь избегать максимально возможного использования new в C ++.

Вывод:
Лучшее решение здесь - использовать std::string, потому что это избавляет вас от всех вышеперечисленных проблем.

3 голосов
/ 09 ноября 2011

str не указывает ни на что разумное.Вам нужно иметь память для записи.

std::string str;
std::cout << "please enter string: ";
std::cin >> str;
2 голосов
/ 09 ноября 2011

Вы должны использовать std::string вместо.

Ваша декларация:

char * str;

объявляет только указатель, но не выделяет область памяти для строки, которая будет сохранена. Решения могли быть

char str[256];

или

char * str = new char[256];

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

C ++ предоставляет std::string для хранения строк. Используйте это.

1 голос
/ 09 ноября 2011

Ваша первая строка, char * str объявляет необработанный указатель и не инициализирует его и не выделяет какую-либо память.Это означает, что он может указывать куда угодно, и, скорее всего, не где-то действительный или полезный.Скорее всего, вы segfault, когда вы пытаетесь использовать его на 3-й строке.Можете ли вы использовать std::string вместо этого?Это будет намного проще и безопаснее, чем необработанные C-струны.

0 голосов
/ 09 ноября 2011

Ошибки сегментации возникают, когда программа обращается к памяти, которая ей не принадлежит.Указатель str не инициализирован.Это не указывает ни на какую память.Оператор извлечения потока >> не выделяет новую память для строки, которую он читает;он ожидает, что указатель уже указывает на буфер, который он может заполнить.Однако он не знает, что str - это мусор.Предполагается, что это действительный указатель и пытается записать в эту память.Так как память по этому адресу мусора не принадлежит вашей программе, ОС останавливает ее с ошибкой сегментации.Еще лучше, используйте std::getline, чтобы пользователь мог ввести строку с пробелами;оператор >> будет читать только до первого символа пробела.

std::string str;
std::getline(cin, str);
0 голосов
/ 09 ноября 2011

Вам нужно сначала выделить память для str. Вы объявили только указатель

char* str = (char*)malloc(MAX_SIZE_OF_BUFFER);
0 голосов
/ 09 ноября 2011

Используйте std::string.

Или, если вы просто хотите использовать char * (не рекомендуется):

char * str = new char[256];
cin >> str;
...