2013-05-22 3 views
4

Вчера у меня была небольшая проблема с самодельной «сложной» функцией. Сейчас это работает, но я немного смущен!Разница между массивом и указателем

char* a = "Hello, World!"; //Works 
char b[] = "Hello, World!"; //Works also 

strcpy(a, "Hello!"); //Segmentation fault 
strcpy(b, "Haha!!"); //Works.. 

В чем разница? Почему указатель char вызывает «ошибку сегментации»?

Почему это даже работает? :

char* a = "Haha"; //works 
a = "LOL"; //works.. 
+0

Я удалил тег C++, так как это о подмножестве C (и даже там вы бы не реализовали 'strcpy' самостоятельно). –

+0

Прочтите этот раздел FAQ по C: http://c-faq.com/aryptr/aryptr2.html – Claudio

+0

@honk да, это имеет смысл –

ответ

14
char* a = "Hello, World!"; 

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

char* a = "Haha"; //works 
a = "LOL"; //works.. 

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

char b[] = "Hello, World!" 

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

+0

, так что я не могу изменить даже один символ в указателе символов, не так ли? –

+2

@NormalPeopleScareMe Правильно. Он указывает на строку * constant *. –

+4

Ну, это неопределенное поведение, так что это может сработать, а может и нет. Мой совет - всегда предполагать, что этого не произойдет. –

1

В первом примере, когда вы пытаетесь записать в память только для чтения, обозначенную символом a, вы получите ошибку сегментации. Если вы хотите использовать указатели, тогда выделите память на кучу, используйте и удалите ее после ее использования , Где b - массив символов, инициализированный «Hello, World!».

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

+0

Я нахожу этот ответ очень полезным. Я не знал, что строковый литерал находится в памяти только для чтения. Также я нашел учебное пособие, как использовать указатели на символы в комбинации с strcpy, которые вызвали ошибку сегментации здесь, и они выделяли память, и я не мог повторить, почему они это сделали. Благодарю. –

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