Char * p и scanf - PullRequest
       4

Char * p и scanf

6 голосов
/ 04 февраля 2011

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

#include<stdio.h>
int main(void){
char* p="Hi, this is not going to work";
scanf("%s",p);
return 0;
}

Насколько я понял, я создал указатель p на смежную область в памяти размером 29 + 1 (для\ 0).Почему я не могу использовать scanf для изменения содержимого этого?

PS Пожалуйста, поправьте меня, если я сказал что-то не так о char *.

Ответы [ 4 ]

14 голосов
/ 04 февраля 2011
char* p="Hi, this is not going to work";

это не выделяет память для записи

это создает String Literal, что приводит к Undefined Behaviour каждый раз, когда вы пытаетесь изменить его содержимое.

для использования p в качестве буфера для scanf сделать что-то вроде char * p = malloc(sizeof(char) * 128); // 128 is an Example

OR

Вы могли бы также сделать:

char p[]="Hi, this is not going to work";

То, что я думаю, это то, что вы действительно хотели сделать.

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

помните:

char * p является строковым литералом и не должен изменяться

char p[] = "..." выделяет достаточно памяти для хранения строки внутри "..." и может быть изменено (я имею в виду его содержимое).

Редактировать:

Хороший трюк, которого следует избегать UB это

char * p = malloc(sizeof(char) * 128);
scanf("%126s",s);
6 голосов
/ 04 февраля 2011

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

0 голосов
/ 04 февраля 2011

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

Надеюсь, что это отвечает на ваш вопрос

0 голосов
/ 04 февраля 2011

scanf() анализирует данные, введенные со стандартного ввода (обычно с клавиатуры).Я думаю, что вы хотите sscanf().

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

Обратите внимание, что sscanf() принимает дополнительный аргумент в качестве первого аргумента, который определяет анализируемую строку.

...