2013-09-02 2 views
-2
#include <stdio.h> 
#include <string.h> 

int main(void){ 

char s1[30]="abcdefghijklmnopqrstuvwxyz"; 

printf("%s\n",s1); 

printf("%s",memset(s1,'b',7)); 

getch(); 

return 0; 
} 

Над кодом работает, но когда я создаю массив s1, как это,В чем отличие этих объявлений массивов?

char *s1="abcdefghijklmnopqrstuvwxyz"; 

это не дает каких-либо ошибок во время компиляции, но не запускается во время выполнения.

Я использую Visual Studio 2012.

Вы знаете, почему?

Я нашел прототип MemSet является:

void *memset(void *s, int c, size_t n); 
+0

не удается ?? Какая ошибка? Не выводится ли выход? Вывоз мусора? –

+0

Необработанное исключение в 0x0F251CF5 (msvcr110d.dll) в C_Son38.exe: 0xC0000005: место записи нарушения доступа 0x00D15858. (Перерыв, Продолжить, Игнорировать кнопки) – Lyrk

+0

Вы пишете только сегмент памяти только для чтения. Как уже объяснялось в ответах –

ответ

4

char s1[30] выделяет перезаписываемый сегмент памяти для хранения содержимого массива, char *s1="Sisi is an enemy of Egypt."; не делает - тот только устанавливает указатель на адрес строки постоянной , который компилятор обычно будет размещать в разделе только для чтения объектного кода.

+0

да, и если вы добавите const char * s1 = "blah"; чем описание указателя более актуально, и оно добавит компиляционную ошибку, если вы передадите указатель константы char вместо указателя char. – cerkiewny

4

String literals получает пространство в разделе «только чтение-данные», которое отображается в пространстве процесса только для чтения (поэтому вы не можете его изменить).

2
char s1[30]="abcdefghijklmnopqrstuvwxyz"; 

Объявляет s1 как массив типа полукокса, и инициализируется его.

char *s1="abcdefghijklmnopqrstuvwxyz"; 

поместит «АБВГДЕЖЗИКЛМНОПРСТУФХЧШЭЮЯ» в режиме только для чтения части памяти и сделать указатель на этот вопрос.

Однако модификация s1 до memset дает undefined behavior.

0

Очень хороший вопрос !.

Если вы НКУ выходной узел, и сравните результат, вы можете найти ответ, и следующий почему:

  • char s1[30]="abcdef";
    • когда определяется в функции, она будет определить массив char, а s1 - это имя массива. Программа будет выделять память в стеке.
    • Определяет глобально, определяет объект в программе и объект не является только для чтения.
  • char* s2 = "abcdef"; только определить точку полукокса, которые указывают на сопзЬ полукокса, хранящегося в .rodata, то есть только для чтения данных в программе.

Чтобы программа работала эффективно и облегчала управление прогрессом, компилятор будет генерировать разные разделы для заданного кода. Константные символы, такие как char* s2 = "abcdef"; и строка формата printf, будут сохранены в разделе .section rodata. После загрузки в основную память загрузчиком ОС этот раздел будет отмечен как только для чтения. Вот почему, когда вы используете memset для изменения памяти, на которую указывает s2, он будет жаловаться Segment fault.

Описание: Difference between char* and char[]

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