2013-08-22 3 views
-1

Это работает:вина Сегментация с зЬгсру()

int main() 
{  
    char *t = "Hello"; 
    t = "World"; 
    printf("%s", t); 
} 

Но это дает ошибку сегментации:

int main() 
{ 
    char *t = "Hello"; 
    strcpy(t, "World"); // the only difference 
    printf("%s", t); 
} 

Почему?

+0

Я использую gcc-компилятор – user2076561

+1

'char * t =" Hello ";" - это указатель, который указывает на строковый литерал. Вы можете свободно назначить его другому строковому литералу, но не можете «хранить» некоторые данные (строка например, в этой памяти.Это была суть ответа, ниже которого я думаю, что кто-то занижен - если вы один из них - пожалуйста, перейдите и верните его обратно. –

ответ

4

В первом примере указатель t сделан для указания на константу строки "Hello", а затем сразу же после этого на константу строки "World"; последнее значение затем печатается.

Код во втором примере сбой с segfault, поскольку строковые константы не могут быть записаны. (strcpy пытается изменить память, содержащую текст "Hello"). GCC помещает строковые константы в раздел только для чтения, если не скомпилирован с -fwriteable-strings.

Код

char *test = "Hello"; 

означает, что компилятор + компоновщик место строка байтов «Hello \ 0» в режиме только для чтения раздела, и test точки в первый символ его. Любая попытка написать через этот указатель будет жестко наказана операционной системой.

С другой стороны

char test[] = "Hello"; 

объявляет массив из 6 символов, с начальным значением ({ 'H', 'e', 'l', 'l', 'o', '\0' }).

Некоторые старые программы предполагали, что строковые константы можно записать; поэтому GCC поддерживает компиляцию этих программ с помощью переключателя командной строки -fwriteable-strings.

+0

, то как насчет первой программы (t = "world") – user2076561

+0

@ user2076561 Поскольку 'p' является указателем, это не то же самое, что и строковый литерал. –

+0

@ user2076561 В первой программе вы не пишете' 'World '' где '' Hello' 'раньше, вы делаете указатель указывает в другом месте. –

3

Первое изменение значения t на адрес от "Hello" по адресу "World". Вторая попытка перезаписать данные "Hello".

1

«Hello» - это константа строки. Он не предназначен для написания, по определению константа.

В вашем первом примере «t» является указателем, и он может указывать (назначать) либо строчную константу.

5

Строки, которые вы определяете явно - например. "Hello" - обычно помещаются в область постоянной памяти. Эти строки не могут быть изменены.

В первом примере вы не меняете строку «Hello» в строку «World». Вы переустанавливаете t так, чтобы он пунктов в «Мир» вместо «Привет». Строка «Hello» все еще висит вокруг, нетронутая, в памяти только для чтения.

Вот начальное состояние:

t -> "Hello" 
    "World" 

Вот второе состояние:

 "Hello" 
t -> "World" 

Во втором примере, вы пытаетесь перезаписать "Hello" строку. Это невозможно.

Вы должны действительно изменить свое заявление от char *t до const char *t. Я думаю, что GCC можно настроить таким образом.

1

В char *t="Hello"t назначить «Привет» в месте только для чтения. Таким образом, запись в исходное местоположение делает ошибку сегментации.

Существует разница между назначением и копированием.

В первом примере вы пытаетесь присвоить адрес другой строки t.

Во втором примере вы пытаетесь записать в исходное местоположение.

использование char t[] = "Hello". Здесь т может быть перезапись более

объяснения Here

2

уступки t = "World" изменяется только указатель, в то время как strcpy изменяет память к которой т точкам. Строковые литералы могут жить в сегменте, доступном только для чтения.

2

char* t - указатель. В первом примере вы просто присваиваете указатель из одного строкового литерала другому: сначала t указал на "Hello", затем на "World". Это совершенно законно.

Однако струнные литералы сами по себе являются литералами - их нельзя изменить. Обычно они находятся в разделе памяти только для чтения. Во втором примере вы пытаетесь изменить то, что находится в памяти, выделенной для строкового литерала "Hello", переписав его "World". Это незаконно, и вы получите ошибку сегментации.

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