[OCLUG-devel] strcpy segmentation faults

Christopher Smith x at xman.org
Fri Jun 24 12:52:56 PDT 2005


Doug Jolley wrote:
>>5) Because it's declared "char*" (as opposed to const char*),
>>REALLY_CONSTANT itself is not constant, nor is it necessarily pointing
>>to a constant. It's just the stuff it's pointing to initially is
>>(because it's a literal string). 
> 
> 
> Well, if you would have left out the phrase beginning with 'nor', I
> would have said that I get it.  The difference between 'char*' and
> 'const char*'  is that 'char*' is a pointer variable (that may be
> changed) and is pointing to a literal/constant string while 'const
> char*' is a pointer constant pointing to the same thing.

No. a 'char*' is a pointer variable pointing to a string. In this case
it starts out pointing to a string literal, but it need not be that way.

Similarly, "const char*" is not a pointer constant. That'd be 'char*
const' (and yes, that is a touch confusing). "const char*" means you
have a non-constant pointer pointing to a constant string, or more
accurately, a string that cannot be modified from said pointer (in
practice the string need not be constant, so long as it's modified by
accessing it from a different pointer).

Perhaps the bigger point that is not being expressed well here is that
typing information is *about the variable*, not about the value. So, you
can have a "char*" and a "const char*" pointing to the same address.
Different rules will apply to what you can do with data at that address
depending on which variable you use to access it. Seperately, you can
have restrictions on the memory at that address (i.e. it might be a
literal, it might already be free()'d, etc.)

> It sounds like you see a distinction between a string constant and
> a string literal.  I'm not sure I understand that distinction.

There is a small and subtle difference. A string literal is a literal
embedded in the code. It's value is embedded inside the program code.
Based on recent revs of gcc and C99, it is required to be constant.
However, you can also have a string constant that who's value is not
embedded in the code. For example I might get the value from a database
or a configuration file.

To illustrate the point, here's some pseudo code:

void illegal_foo(const char* bar) {
    bar[1] = 'c'; /* illegal, shouldn't compile */
}

void foo(char* bar) {
    bar[1] = 'c';
}

char* var1 = "can't change me";
const char* var2 = "safer way to define it";
char* var3 = (char*) alloca(strlen(var1)+1);
const char* var4 = var3;
strcpy(var3, var1);
foo(var1); /* segfault */
foo(var2); /* illegal type for parameter "bar", shouldn't compile */
illegal_foo(var2); /* this is valid, but of course the definition of

                      illegal_foo isn't so it's hardly of much value */
foo(var3); /* legal, and it won't segfault */
foo(var4); /* illegal, but if the compiler ignores const anyway,
              no segfault */

--Chris


More information about the OCLUG-devel mailing list