Инициализация другой строки приводит к другому поведению? - PullRequest
1 голос
/ 30 октября 2009

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

while (*postcode) {
    *postcode = toupper(*postcode);

    postcode++;
}

Использование следующего аргумента работает,

char wrong[20];
strcpy(wrong, "la1 4yt");

Но не так ли это, несмотря на то, что они одинаковые?

char* wrong = "la1 4yt";

Моя программа дает сбой при попытке записи на недопустимый адрес (я полагаю, это ошибка). Это проблема с не malloc ING? Не быть нулевым? Это не должно быть ...

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

Любая помощь приветствуется!

Ответы [ 5 ]

5 голосов
/ 30 октября 2009
char* wrong = "la1 4yt";

Это объявляет указатель на строковую константу. Константа не может быть изменена, поэтому ваш код падает. Если вы написали более педантичный

const char* wrong = "la1 4yt"; // Better

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

Это, с другой стороны, выделяет хранилище для чтения / записи для двадцати символов, так что запись в пробел вполне подойдет.

char wrong[20];

Если вы хотите инициализировать его в строке выше, вы можете сделать это, и тогда вам будет разрешено изменить его.

char wrong[20] = "la1 4yt"; // Can be modified
char wrong[]   = "la1 4yt"; // Can be modified; only as large as required
2 голосов
/ 30 октября 2009

См. Вопрос 8.5 в списке часто задаваемых вопросов C.

2 голосов
/ 30 октября 2009

Во втором варианте "la1 4yt" является константой и поэтому находится в сегменте только для чтения. Только указатель (wrong) на константу доступен для записи. Вот почему вы получаете Segfault. Однако в первом примере все доступно для записи.

Это может быть интересно: http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c/

2 голосов
/ 30 октября 2009
char * whatever = "some cont string";

Только для чтения.

1 голос
/ 30 октября 2009

Когда вы делаете

char wrong[20] = "la1 4yt";

компилятор копирует элементы строкового литерала {'l', 'a', '1', ' ', '4', 'y', 't', '\0'} в соответствующие элементы массива wrong; когда вы делаете

char *wrong = "la1 4yt";

компилятор присваивает wrong адрес строкового литерала.

Строковые литералы char[] (массивы символов), а не const char[] ... но вы не можете их изменить !!

Цитата из стандарта:

6.4.5 String literals
6   It is unspecified whether these arrays are distinct provided
    their elements have the appropriate values. If the program
    attempts to modify such an array, the behavior is undefined.

Когда я использую строковый литерал для инициализации char *, я обычно также говорю компилятору, что не буду изменять содержимое этого строкового литерала, добавляя const к определению.

const char *wrong = "la1 4yt";

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

Предположим, у вас было

char *test1 = "example test";
char *test2 = "test";

И компилятор создал 1 однострочный литерал и использовал этот однострочный литерал для инициализации test1 и test2. Если вам было разрешено изменить строковый литерал ...

test1[10] = 'x';       /* attempt to change the 's' */
printf("%s\n", test2); /* print "text", not "test"! */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...