#include<stdio.h>
#include<stdlib.h>
 #include<string.h>
void main()
{  char* a[10]={"asd","QWE","ghj"};
   printf("%s %c",a[2],a[2][2]);             // prints properly... "ghj j"
   puts(a[1]);                                     //prints  properly..."QWE"
   a[1][1]='t';                                //gives segmentation fault....
}

what is the mistake in the code...??/..pls help..have an exam in 6 hrs...thank you....

Edited 5 Years Ago by Narue: Added code tags

char* a[10]={"asd","QWE","ghj"}

On this line, you are assigning const char* (everything between "'s) to a char* (elements of a).
So when you try to modify something at a[1][1] you are trying to modify a const char* indirectly. Because this constant data ("asd", "QWE", etc.) is stored in a special read-only section in memory you are getting a segmentation fault.

Edited 5 Years Ago by thelamb: n/a

If you only read the elements of a then everything is fine, yes.
Also, please don't be so lazy to write 'd' for 'the' - it is very annoying to read sentences like that.

Also, please don't be so lazy to write 'd' for 'the' - it is very annoying to read sentences like that.

This^^^

Because this constant data ("asd", "QWE", etc.) is stored in a special read-only section in memory you are getting a segmentation fault.

Just a clarification: String literals may be stored in read-only memory. Borland compilers in particular have historically allowed modification of string literals due to not storing the string in read-only memory. The reason the standard allows them to be read-only is twofold:

  1. Compiler writers have the option of placing string literals in a more convenient part of the object file for constant data.
  2. For space saving purposes, string literals with the same contents may point to the same underlying array object.

The provision for allowing read-only string literals is indirect though. The standard says that attempts to modify a shared string literal are undefined, which implies #2 and to a lesser extent #1 since it's a logical precursor to #2.

However, the standard uses tricky wording. It's unspecified whether the array pointed to by a string literal is unique, and an attempt to modify the array invokes undefined behavior, but it's not entirely clear if the undefined behavior is conditional upon the array being shared (though that's my preferred interpretation).

In strictly portable code, it's best practice to assume the most restrictive storage of string literals and treat them as both shared and read-only.

Comments
Hm, did not know it was up to implementers. Thanks for clarifying

So what do you do then if you want to use a string literal, and guarantee that you'll be able to edit it later? Create a constant for it, then use strcpy() (or similar)?

I suppose it makes sense, its sort-of considered "best practice" when working with numeric literals (as opposed to using "magic numbers")...

Edited 5 Years Ago by Fbody: n/a

So what do you do then if you want to use a string literal, then guarantee that you'll be able to edit it later?

If you view string literals as memory that you don't own, you can roll this up into the guideline of making an owned copy to guarantee control. So yes, you'd allocate your own array of the correct size and copy the contents of the string literal into that array.

Or since this is C++, make a std::string object. :)

So the issue only affects C-style char arrays? You won't run into that issue with an std::string object?

Interesting. That's good to know... :)

Edited 5 Years Ago by Fbody: n/a

So the issue only affects C-style char arrays? You won't run into that issue with an std::string object?

This particular issue only affects string literals when you want to modify them. The std::string implementation may use a copy on write implementation where the underlying array is shared until you try to write to the string (then a copy is made), but that's all hidden under the hood.

This article has been dead for over six months. Start a new discussion instead.