Проблема назначения строки компилятора Gcc C

Я написал этот код, потому что у меня возникла аналогичная проблема в более крупной программе, которую я пишу. Насколько я знаю, проблема та же самая, поэтому я сделал этот небольшой пример.

#include <stdio.h>

typedef struct
{
    int x;
    char * val;
}my_struct;

int main()
{
    my_struct me = {4, " "};
    puts("Initialization works.");
    me.val[0] = 'a';
    puts("Assignment works.");
    puts(me.val);
    puts("Output works.");
    return 0;
}

При компиляции с помощью tcc (Tiny C Compiler) он компилируется и выполняется нормально. Но с использованием GCC 4.6.0 20110513 (предварительная версия) он компилируется, однако, когда я его запускаю, я получаю только «Инициализация работает». прежде чем получить segfault.

Что я делаю не так? Это мой код или мой компилятор GCC?


person Tnelsond    schedule 04.06.2011    source источник
comment
Этот ответ говорит об этом хорошо.   -  person ladaghini    schedule 04.06.2011


Ответы (3)


Ваш код. ANSI допускает, чтобы строковые константы были доступны только для чтения, и это поощряется, потому что это означает, что они могут быть общими для всей системы во всех запущенных экземплярах программы; gcc делает это, если вы не укажете -fwritable-strings, в то время как tcc делает их доступными для записи (вероятно, потому что это проще).

person geekosaur    schedule 04.06.2011
comment
Спасибо. Так я делаю его доступным для записи? Мне нужно создать массив символов и связать его, а не указатель на строку? - person Tnelsond; 04.06.2011
comment
@Tnelsond: вам не следует полагаться на такое поведение, а вместо этого не инициализировать char* из const char[] (которое вырождается в const char*). Вместо этого используйте копию. - person rubenvb; 04.06.2011
comment
Итак, я должен использовать функцию strcpy из строкового литерала, чтобы создать модифицируемую строку? - person Tnelsond; 04.06.2011
comment
@tnelsond: В идеале да. Строки C... примитивны. (Строки — это основная причина, по которой я практически перестал использовать C. По возможности придерживайтесь строк C++.) - person geekosaur; 04.06.2011

val указывает на местоположение только для чтения.

char *readOnly = "Data in read only location" ;

readOnly данные наведения не могут быть изменены.

person Mahesh    schedule 04.06.2011

Как указывали другие ответы, val указывает на строковую константу. Пытаться

my_struct me = {4, malloc(2)};

и не забудьте проверить, является ли val NULL, если вы используете это в реальной программе.

person sverre    schedule 04.06.2011
comment
О, вот как бы я это сделал. Так что я должен освободить строку malloc после этого, верно? Или он сам освободится при выходе из программы? - person Tnelsond; 04.06.2011
comment
@Tnelsond - вам нужно явно освободить ресурсы, используя free. - person Mahesh; 04.06.2011
comment
Мне нужно освободить его, даже если моя программа закрывается? Если это так, было бы лучше для меня просто создать массив символов и сослаться на него, а не выделять память с помощью malloc? - person Tnelsond; 04.06.2011
comment
@Tnelsnod вам не нужно вызывать free, если ваша программа завершается, но вы сказали, что дали нам пример кода, который использовался в более сложной программе, в этом случае вам следует остерегаться возможных утечек памяти, если вы этого не сделаете. т освободить память. - person sverre; 04.06.2011