Коли ви пишете "рядок" у своєму вихідному коді, він записується безпосередньо у виконуваний файл, оскільки це значення потрібно знати під час компіляції (є інструменти, які дозволяють розібрати програмне забезпечення та знайти в ньому всі текстові рядки). Коли ви пишете char *a = "This is a string"
, розташування "Це рядок" знаходиться у виконуваному файлі, а місце, яке a
вказує на, знаходиться у виконуваному файлі. Дані у виконуваному зображенні доступні лише для читання.
Що вам потрібно зробити (як зазначають інші відповіді), це створити цю пам’ять у місці, яке не лише для читання - у купі або у фреймі стека. Якщо ви оголосите локальний масив, тоді для кожного елемента цього масиву в стеці буде зроблено пробіл, і літеральний рядок (який зберігається у виконуваному файлі) копіюється в цей простір у стеку.
char a[] = "This is a string";
Ви також можете скопіювати ці дані вручну, виділивши трохи пам’яті в купі, а потім strcpy()
скопіювавши рядковий літерал у цей простір.
char *a = malloc(256);
strcpy(a, "This is a string");
Кожного разу, коли ви виділяєте місце за допомогою, не malloc()
забудьте зателефонувати, free()
коли закінчите з ним (читайте: витік пам'яті).
В основному, ви повинні відстежувати, де знаходяться ваші дані. Щоразу, коли ви пишете рядок у своєму джерелі, цей рядок є лише для читання (інакше ви могли б потенційно змінити поведінку виконуваного файлу - уявіть, якщо ви писали, char *a = "hello";
а потім змінили a[0]
на 'c'
. Тоді десь ще писали printf("hello");
. Якби вам дозволили змінити перший символу "hello"
, і ваш компілятор зберігав його лише один раз (він повинен), а потім printf("hello");
вивів би cello
!)