0

I wrote this code because I'm having a similar problem in a larger program I'm writing. For all I know the problem is the same so I made this small example.

#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;
}

When compiled with tcc (Tiny C Compiler) it compiles and executes fine. But using GCC 4.6.0 20110513 (prerelease) it compiles, however, when I execute it I only get past "Initialization works." before getting a segfault.

What am I doing wrong? Is it my code or my GCC compiler?

Tnelsond
  • 45
  • 7
  • [This answer](http://stackoverflow.com/questions/164194/why-does-simple-c-code-receive-segmentation-fault/164258#164258) says it well. – ladaghini Jun 04 '11 at 19:05

3 Answers3

8

Your code. ANSI permits string constants to be read-only, and this is encouraged because it means they can be shared system-wide across all running instances of a program; gcc does so unless you specify -fwritable-strings, while tcc makes them writable (probably because it's easier).

geekosaur
  • 59,309
  • 11
  • 123
  • 114
  • Thanks. So I make it writable? I have to create an array of characters and link to that rather than a pointer to a string? – Tnelsond Jun 04 '11 at 19:09
  • @Tnelsond: you shouldn't rely on that behavior, and instead *not* initialize a `char*` from a `const char[]` (which degenerates in `const char*`). Use a copy instead. – rubenvb Jun 04 '11 at 19:22
  • So I should use the strcpy function from a string literal to make a modifiable string? – Tnelsond Jun 04 '11 at 19:49
  • @tnelsond: Ideally, yes. C strings are... primitive. (Strings are the primary reason I stopped using C for much of anything. Stick to C++ strings whenever possible.) – geekosaur Jun 04 '11 at 19:52
0

val is an points to read only location.

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

readOnly pointing data cannot be modified.

Mahesh
  • 34,573
  • 20
  • 89
  • 115
0

As other answers have pointed out, val is pointing at a string constant. Try

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

and remember to check if val is NULL if you're using this in a real program.

sverre
  • 6,768
  • 2
  • 27
  • 35
  • Oh so that's how I'd do it. So I have to free malloced string afterwards right? Or will it free itself on exit from the program? – Tnelsond Jun 04 '11 at 19:15
  • @Tnelsond - You need to explicitly deallocate the resources using `free`. – Mahesh Jun 04 '11 at 19:17
  • I need to free it even if my program is exiting? If that's the case, would it be better for me to just create an array of characters and link to that rather than allocating memory with malloc? – Tnelsond Jun 04 '11 at 19:22
  • @Tnelsnod you don't have to call `free` if your program is exiting, but you said you were giving us an example of code that was used in a more complicated program, in that case you should beware of possibly memory leaks if you don't free your memory. – sverre Jun 04 '11 at 19:35