Когда вы пишете «строку» в исходном коде, она записывается непосредственно в исполняемый файл, потому что это значение должно быть известно во время компиляции (существуют инструменты, позволяющие разобрать программное обеспечение и найти в них все простые текстовые строки). Когда вы пишете 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
!)