HELP - String Space???? 
Author Message
 HELP - String Space????

Hello - Yes, another C student with a question...

I have the following program:

----

#include <stdio.h>

int main() {
  char* s = "123 456";

  s[4]='9';

  printf("%s", *s);

  return 0;

Quote:
}

----

This looks right to me - it should work in my mind - but it doesn't - I
get a SIGBUS and a wonderful core file out of it instead.  I'm running
Linux at home and I've also compiled this on the Sparc (running Solaris)
at school and I get the same {*filter*}y thing.

So.. I asked someone else and they told me that

char* s = "123 456"; ,

when compiled is compiled as pre-defined stringspace, and therefore cannot
by modified.  I don't understand this in the least and would appreciate
explanation.

I assumed that if something was defined such as the above notation, that
it was just a shortcut .. so whether I do:

  void main() {
    char*s = "123 456";
  }

or whether I use:

  #include <string.h>
  void main() {
    char*s;
    strcpy(s, "123 456");
  }

It would be the same thing?? However obviously it is not and I would
appreciate an explanation in beginner terms <g> ..  ;)

-Dan



Tue, 31 Aug 1999 03:00:00 GMT  
 HELP - String Space????

Quote:

>I'm irresistibly reminded of that rather good explanation of undefined
>behaviour by, I think, Steve Summit.  (Rummage, rummage.)  Aha!
>Actually he was quoting one Roger Miller:
>        Somebody once told me that in basketball you can't hold
>        the ball and run.  I got a basketball and tried it and it
>        worked just fine.  He obviously didn't understand basketball.

I REALLY like this example. Thanks to you/Steve Summit/Roger Miller
et.al.

Quote:
>This (I hope) illustrates the point.  Danette & Murray's statement
>is correct.  You can't modify a string literal *in C*.  As soon as
>you attempt to modify one your code is wrong - it isn't legal C.
>C doesn't say the modification won't work - it just says you've wandered
>outside the bounds of what C allows, so anything goes.  You might
>get an (apparently) modified string.  Your program might run one time,
>do nothing at all the second and then crash the third (yes, really - I know
>of one system where exactly this did tend to happen).

Our difference here is the interpretation of the word  *cannot*.  I
take it that *cannot* means you are prevented from doing something i.e
I cannot jump over a building (physically unable to do it). On the
other hand, I accept a not *allowed* category. This I take to mean
something I *can* do but for which there is a, perhaps even dire,
consequense. In  your fine example above, I see it as you *can*  take
the basketball and run but you're not *allowed*  to do it. If you do
you're penalized.

In the case of modifying a string literal, if the compiler prevented
me form compiling the code || the program crashed in all instances,
I'd agree that you *cannot* modify a string literal in C. For it not
being legal, I agree entirely.

Initially, I tried this to see what error message it would produce. It
produced none, hence this discussion. I'm very surprised that the
compiler does not prevent me from doing this. It does not seem that it
would be difficult for the compiler to recognize that it is a string
literal and for it to prevent me from doing this.

Because undefined behaviour in invoked; it won't work at all on some
platforms; it works intermittently on some platforms etc. I think is
an example of not *allowed*.

Quote:
>So the statement is correct - you can't modify a string literal in C.
>What you can do outside C is of no concern to the ISO standard.

But I thought the job of the compiler was to conform to the standard.
I don't want to draw this out too much but it has raised some
questions for me regarding the way compilers react to things which the
standard would indicate will invoke undefined behavior.

It seems that the compiler folks let the  void main() undefined
behavior slip by, though I don't see a really good reason to do so.
It seems it would have been just as easy and more efficient for them
to have indicated an error if main didn't return an int. I can only
guess that since I've seen some old books where void main() was used
it has something to do with backward compatifility to some time before
the standard was adopted or defined the int return.  However, this
modifying of string literals seems to me to be vastly more perilous.
If it's not legal according to the standard and  if I am correct in
assuming that there is no instance where modifying a string literal is
reasonable, why not just prevent it.  In following the message thread
here regarding modulus, I can see that some latitude in interpretation
by the compiler people was probably necessary but I can't see the same
for say, int main() and certainly not for modifying string literals.

I appreciate your and Murray's help. I just like knowing why something
is the way it is. I was never very good with just memorizing something
and not understanding why.



Tue, 31 Aug 1999 03:00:00 GMT  
 HELP - String Space????

(snip my previous)

Quote:
>Do consider for a moment how *you* might implement run-time memory
>protection under MS-DOS before you ask the compiler to.  Under many
>versions of Unix it's a simple matter of clustering the string literals
>and marking that range of memory as write-protected.

Sorry, implementing run-time memory protection under MS-DOS is way
beyond my ability to even contemplate, but thanks for asking :-). I
guess what I thought should happen and believed possible is this. If
clustering the string literals is a simple matter for Unix then it
seems to follow that under MS-DOS the string literals could at least
be recognized as such by the compiler code. Given the ability to
recognize a string literal it doesn't seem it would be difficult or
unreasonable to expect the compiler to generate a message (preferably
an error) if an attempt to modify the string literal is made. After
all, isn't this an attempt to violate the standard?

(snip my previous)

Quote:
>Since when does the behavior of a Borland compiler suffice as the
>definition of the C language?  String literals are *not* writable in
>C, and Borland does not implement protection to enforce that.

I'm not making my self clear, I guess. I am not saying that the
behavior of Borland or any other compiler defines the C language. God
Forbid! I am a proponent of the behavior of compilers not allowing
deviations from what the standard indicates.

I'm totally in favor of extensions to the C language though they might
be platform and/or compiler specific. I wouldn't trade Borland's
conio's ability to clear the screen with a simple clrscr(). I'm very
glad I don't have to use ansi escape codes any more to do it and worry
about a machine not having ansi.sys loated.. I pity anyone who must
scroll the screen with blank lines or write any extra code to
accomplish this or be satisfied with a clumsy user interface. However,
I know conio is not ansi C and can take this into account if I were to
port an application. I see no justification for the compiler allowing
modification of a string literal using only standard libraries without
at least a warning.

Quote:
>IOW, please imagine what the C language would be if it was defined
>according to what every compiler does and does not do.  Compilers
>for freestanding implementations often don't provide a full set of
>the standard library - does that mean we should advice against the
>use of the standard library because some compilers that have the
>letter "C" in their names do not support it?  Some bonafide C
>compilers also don't support ANSI parameter formats in function
>declarations - do we advice against that as well?

I know it's my responsibilty to learn the proper use of the language
and not knowingly violate any of it's provisions. I knew I wasn't
supposed to modify a string literal and, in fact or perhaps luckily,
hadn't tried until I tried this example just to see what would happen.
This is where I feel the compiler has not lived up to it's
responsibilty to conform to the C language standard. I was previously
unaware that the compiler, which I feel is from a reputable
manufacturer,  would allow this without an objection.  I've placed a
lot of faith in the compiler checking errors for me and this is one I
think it should catch.

I know  this has gotten off topic and appreciate the indulgence and
the help. To reiterate, my concern is not with the C standard but with
the compilers latitude in enforcing it.

Quote:
>[...]



Tue, 31 Aug 1999 03:00:00 GMT  
 HELP - String Space????

Quote:

>Hello - Yes, another C student with a question...
>I have the following program:
>----
>#include <stdio.h>
>int main() {
>  char* s = "123 456";

>  s[4]='9';

I think what  you mean here is printf("%s", s) and if that's a space
in the string you're trying to write the 9 to you'll need s[3]. Given
these, it works for me.
Quote:
>  printf("%s", *s);    
>  return 0;
>}
>----
>This looks right to me - it should work in my mind - but it doesn't - I
>get a SIGBUS and a wonderful core file out of it instead.  I'm running
>Linux at home and I've also compiled this on the Sparc (running Solaris)
>at school and I get the same {*filter*}y thing.
>So.. I asked someone else and they told me that
>char* s = "123 456"; ,
>when compiled is compiled as pre-defined stringspace, and therefore cannot
>by modified.  I don't understand this in the least and would appreciate
>explanation.
>I assumed that if something was defined such as the above notation, that
>it was just a shortcut .. so whether I do:
>  void main() {
>    char*s = "123 456";
>  }
>or whether I use:
>  #include <string.h>
>  void main() {
>    char*s;
>    strcpy(s, "123 456");
>  }
>It would be the same thing?? However obviously it is not and I would
>appreciate an explanation in beginner terms <g> ..  ;)
>-Dan



Wed, 01 Sep 1999 03:00:00 GMT  
 HELP - String Space????


wrote in comp.lang.c:

=> #include <stdio.h>
=> int main() {
=>   char* s = "123 456";
=>  
=>   s[4]='9';
=>   printf("%s", *s);
=>   return 0;
=> }

=> So.. I asked someone else and they told me that

=> char* s = "123 456"; ,

=> when compiled is compiled as pre-defined stringspace, and therefore cannot
=> by modified.  I don't understand this in the least and would appreciate
=> explanation.

Fancy way of saying that a string literal can be placed into a block of memory
you aren't allowed to write to. It may be a code block, a separate 'string
block', whatever. This allows the compiler to remove duplications of the
string and do other nice optimizations.

=> I assumed that if something was defined such as the above notation, that
=> it was just a shortcut .. so whether I do:

=>   void main() {
=>     char*s = "123 456";
=>   }

here you are giving s the address of the string literal, which most likely
resides in read-only space.

=> or whether I use:

=>   #include <string.h>
=>   void main() {
=>     char*s;
=>     strcpy(s, "123 456");
=>   }

=> It would be the same thing??

two problems:
- s is an unitialized pointer. It doesn't point anywhere useful, and using it
would probably cause whatever memory faults your OS supports to be generated.
Or, you might get lucky and it could work, sometimes. You need to use
something like malloc() [malloc() works just fine for this] to allocate some
memory, THEN do the strcpy().

- you are COPYING from the literal to the address pointed to by s. Perfectly
legal, since string space is readable, just not writeable.

One way you CAN use a string literal to initialize writeable memory-

char s[]="123 456";

which gives you an array of eight chars
s[0] = '1'
s[1] = '2'
...
s[6] = '6'
s[7] = '\0'

that you can use as a string, as long as you don't try to write more than
seven characters into it.

<><><><><><><><><><><><><><><><><><><><>

Wizard's First Rule:
    People are stupid.
Wizard's Second Rule:
    Never depend on the first rule.

<><><><><><><><><><><><><><><><><><><><>



Wed, 01 Sep 1999 03:00:00 GMT  
 HELP - String Space????


wrote in comp.lang.c:


=> >Hello - Yes, another C student with a question...

=> >I have the following program:

=> >----

=> >#include <stdio.h>

=> >int main() {
=> >  char* s = "123 456";
=> >                      
=> >  s[4]='9';

=> I think what  you mean here is printf("%s", s) and if that's a space
=> in the string you're trying to write the 9 to you'll need s[3]. Given
=> these, it works for me.

Ahem. This is c.l.c the 'it works for me' argument is inappropriate here. The
ANSI/ISO standard is the tool we use to determine whether or not something is
correct [with some exceptions granted for K&R1, if explicitly stated].
String literals cannot be written to (modified) in C.

=> >  printf("%s", *s);    
=> >  return 0;
=> >}

<><><><><><><><><><><><><><><><><><><><>

Wizard's First Rule:
    People are stupid.
Wizard's Second Rule:
    Never depend on the first rule.

<><><><><><><><><><><><><><><><><><><><>



Wed, 01 Sep 1999 03:00:00 GMT  
 HELP - String Space????


Quote:

>wrote in comp.lang.c:

>=> >Hello - Yes, another C student with a question...
>=> >I have the following program:
>=> >----
>=> >#include <stdio.h>
>=> >int main() {
>=> >  char* s = "123 456";
>=> >                      
>=> >  s[4]='9';
>=> I think what  you mean here is printf("%s", s) and if that's a space
>=> in the string you're trying to write the 9 to you'll need s[3]. Given
>=> these, it works for me.
>Ahem. This is c.l.c the 'it works for me' argument is inappropriate here. The

Yes, so it is c.l.c. I wasn't lost. 'it works for me' is not an
*argument*. It's a statement and it got me an explanation of why it
was even possible for me to do it under DOS. That being, according to
a Unix user ( and I over simplify his response), DOS has improper
memory protection.

Quote:
>ANSI/ISO standard is the tool we use to determine whether or not something is
>correct [with some exceptions granted for K&R1, if explicitly stated].

I didn't say it was correct. The poster knows it's not correct because
it won't work on his system.

Quote:
>String literals cannot be written to (modified) in C.

 The question was from someone using Linux and it obviously doesn't
work for him. Therefore, he *cannot* do it. In DOS I compiled it
without even a warning. When it compiled and modified the string
literal I was very surprised but I *can* do it. I find this much more
dangerous than if I *cannot* do it. Personally, I think the compiler
should at least issue a warning in this case but, apparently, Borland
doesn't.  So your statement that 'String literals cannot be written to
(modified) in C' is incorrect since it is  possible on the DOS
platform, at least with this Borland compiler. So,  while in some
circumstances you *can* modify a string literal in C , you better not
do it' is more accurate.

I got an excellent email explanation of the possible harmfull effects
of modifying string literals and how differences in memory protection
was why it happened to work for me under DOS while it doesn't in Unix.
I've known you wern't supposed to modify string literals but didn't
really understand why. Since his examples were very clear I now know
why as well.  Had he also sent it to the group, I'm sure it would have
helped other DOS users who might inadvertantly do it, as well.

Thanks for your response, though, and not bothering to point me to
comp.os.msdos.programmer which I've read for some time and found
useless (with the exception of some messages that are cross posted
from this group). The abundance of attitude exhibited here is well
worth the detailed information that's provided by the more experienced
contributers.



Wed, 01 Sep 1999 03:00:00 GMT  
 HELP - String Space????



Quote:

[snip]
>>String literals cannot be written to (modified) in C.

> The question was from someone using Linux and it obviously doesn't
>work for him. Therefore, he *cannot* do it. In DOS I compiled it
>without even a warning. When it compiled and modified the string
>literal I was very surprised but I *can* do it. I find this much more
>dangerous than if I *cannot* do it. Personally, I think the compiler
>should at least issue a warning in this case but, apparently, Borland
>doesn't.  So your statement that 'String literals cannot be written to
>(modified) in C' is incorrect since it is  possible on the DOS
>platform, at least with this Borland compiler. So,  while in some
>circumstances you *can* modify a string literal in C , you better not
>do it' is more accurate.

I'm irresistibly reminded of that rather good explanation of undefined
behaviour by, I think, Steve Summit.  (Rummage, rummage.)  Aha!
Actually he was quoting one Roger Miller:

        Somebody once told me that in basketball you can't hold
        the ball and run.  I got a basketball and tried it and it
        worked just fine.  He obviously didn't understand basketball.

This (I hope) illustrates the point.  Danette & Murray's statement
is correct.  You can't modify a string literal *in C*.  As soon as
you attempt to modify one your code is wrong - it isn't legal C.
C doesn't say the modification won't work - it just says you've wandered
outside the bounds of what C allows, so anything goes.  You might
get an (apparently) modified string.  Your program might run one time,
do nothing at all the second and then crash the third (yes, really - I know
of one system where exactly this did tend to happen).

So the statement is correct - you can't modify a string literal in C.
What you can do outside C is of no concern to the ISO standard.

John
--
John Winters.  Wallingford, Oxon, England.



Wed, 01 Sep 1999 03:00:00 GMT  
 HELP - String Space????


[...]
:  The question was from someone using Linux and it obviously doesn't
: work for him. Therefore, he *cannot* do it. In DOS I compiled it
: without even a warning. When it compiled and modified the string
: literal I was very surprised but I *can* do it. I find this much more
: dangerous than if I *cannot* do it. Personally, I think the compiler
: should at least issue a warning in this case but, apparently, Borland
: doesn't.

Do consider for a moment how *you* might implement run-time memory
protection under MS-DOS before you ask the compiler to.  Under many
versions of Unix it's a simple matter of clustering the string literals
and marking that range of memory as write-protected.

: So your statement that 'String literals cannot be written to
: (modified) in C' is incorrect since it is  possible on the DOS
: platform, at least with this Borland compiler. So,  while in some
: circumstances you *can* modify a string literal in C , you better not
: do it' is more accurate.

Since when does the behavior of a Borland compiler suffice as the
definition of the C language?  String literals are *not* writable in
C, and Borland does not implement protection to enforce that.

IOW, please imagine what the C language would be if it was defined
according to what every compiler does and does not do.  Compilers
for freestanding implementations often don't provide a full set of
the standard library - does that mean we should advice against the
use of the standard library because some compilers that have the
letter "C" in their names do not support it?  Some bonafide C
compilers also don't support ANSI parameter formats in function
declarations - do we advice against that as well?

[...]



Wed, 01 Sep 1999 03:00:00 GMT  
 HELP - String Space????



Quote:
> Given the ability to
>recognize a string literal it doesn't seem it would be difficult or
>unreasonable to expect the compiler to generate a message (preferably
>an error) if an attempt to modify the string literal is made. After
>all, isn't this an attempt to violate the standard?

It isn't easy in all cases, and the standard does not require
a diagnostic for this.

Quote:
> I see no justification for the compiler allowing
>modification of a string literal using only standard libraries without
>at least a warning.

Because it isn't always obvious when a string literal is being modified
when looking at the program from the compiler's vantage point.

Quote:
>This is where I feel the compiler has not lived up to it's
>responsibilty to conform to the C language standard.

This example does not show any failure of your compiler to
comply with the standard.

Quote:
> I was previously
>unaware that the compiler, which I feel is from a reputable
>manufacturer,  would allow this without an objection.  I've placed a
>lot of faith in the compiler checking errors for me and this is one I
>think it should catch.

Ah, quality of implementation -- that's different.  I rather
like gcc's option to "pretend that string literals were array of
const char and warn me when the implications of this show that
I'm doing something questionable" (-Wwrite-strings).  Once I bite
the bullet and declare all the string pointers which work with
string literals to be "const char *", this option often shows me
where I do something questionable.  Most of the time I will work
to eliminate the remaining warnings, though if I'm calling a 3rd
party API which I know really takes a const char *, even though
the function prototype says char *, I'll just live with the warning.

                --Ken Pizzini



Thu, 02 Sep 1999 03:00:00 GMT  
 HELP - String Space????



Quote:
>Initially, I tried this to see what error message it would produce. It
>produced none, hence this discussion. I'm very surprised that the
>compiler does not prevent me from doing this. It does not seem that it
>would be difficult for the compiler to recognize that it is a string
>literal and for it to prevent me from doing this.

In the general case it can be arbritrarily difficult for the
compiler to know that a string literal is being modified.
Thus the fall-back to the catch-all "undefined behavior".

Consider:
int foo(int);
void bar(int xxx) {
    char b[10];
    char *p;
    if (xxx)
        p = "baz";
    else
        p = b;
    if (foo(xxx))
        *p = 'x';

Quote:
}

Now, should the compiler give me a diagnostic?  Since foo() can
be in some other translation unit I don't see how it can decide,
but the programmer could very well know that the semantics of
foo() are such that foo(xxx) is never non-zero when xxx is zero.
(Yes, this example is contrived and shows a questionable coding
practice; it is only intended to illustrate the point of why
the compiler can't be expected to give a diagnostic.)

Quote:
>>So the statement is correct - you can't modify a string literal in C.
>>What you can do outside C is of no concern to the ISO standard.

>But I thought the job of the compiler was to conform to the standard.
>I don't want to draw this out too much but it has raised some
>questions for me regarding the way compilers react to things which the
>standard would indicate will invoke undefined behavior.

The standard left this undefined because:
  A) Substantial legacy code liked to modify string literals, as
     K&R1 allowed this behavior.  Thus latitude must be given to
     implementations which wished to cater to thes applications.
  B) There are benefits to prohibiting modification of string
     literals, and the committee wished to permit implementations
     to take advantage of these benefits.

Quote:
>It seems that the compiler folks let the  void main() undefined
>behavior slip by, though I don't see a really good reason to do so.
>It seems it would have been just as easy and more efficient for them
>to have indicated an error if main didn't return an int. I can only
>guess that since I've seen some old books where void main() was used
>it has something to do with backward compatifility to some time before
>the standard was adopted or defined the int return.

I suspect that compatability with poorly written texts was
one impetus.  Another is that since main() is a special
case in permitting two valid prototypes, compiler writers
decided to just accept any old prototype and try to interpret
whatever happens to be in the "return an int from function"
location as the int returned by main().  For platforms where
this approach makes sense, it is quite an easy thing to do.
(The standard does not say that an implementation which accepts
other than the two blessed prototypes to be is non-conforming.
This allows for implementation-defined extentions, such as
the obsolescent int main(int, char **, char **) prototype which
many Unix compilers still support.

If you have a compiler which accepts void main(void), I'd
be interested to know if it would reject:
    double main(char ***argc, float argv, int envp) { return 0.0; }
My suspicion is that any compiler which accepts void main(void)
will also accept this nonsense without complaint.

Quote:
>  However, this
>modifying of string literals seems to me to be vastly more perilous.
>If it's not legal according to the standard and  if I am correct in
>assuming that there is no instance where modifying a string literal is
>reasonable, why not just prevent it.

The only reasonable way to prevent would be to have string literals
be of type "array of const char" instead of just "array of char".
But this causes "const poisoning" which renders vast quantities
of otherwise legal legacy code to be {*filter*}ed about by the compiler
because of the assignment a string literal to a char * variable.

                --Ken Pizzini



Thu, 02 Sep 1999 03:00:00 GMT  
 HELP - String Space????


Quote:

>the standard was adopted or defined the int return.  However, this
>modifying of string literals seems to me to be vastly more perilous.
>If it's not legal according to the standard and  if I am correct in
>assuming that there is no instance where modifying a string literal is
>reasonable, why not just prevent it.

But there may be instances where a compiler should consider
the modification of string literals. Before a change in the
standard, sting literals were modifiable. Only later did the
standard change making string literals no longer modifiable,
and so they may be placed in read-only memory. If
a compiler complied only with the new standard then code
written prior to the change would be obselete.
Compilers chose to deal with the issue in different ways.
So, in the end, you will find compilers that accept
modification and some that will not. Also, you will
find code written when modification was accepted
practice. Unfortunately, this code now evokes
undefined behavior.

My advise is to take the safe route,; do not
intentionally evoke undefined behavior. Adhere to
to standard and do not modify string literals.

Al Bowers                                
Tampa, FL

http://www.gate.net/~abowers/index.html



Thu, 02 Sep 1999 03:00:00 GMT  
 HELP - String Space????



: (snip my previous)
: >Do consider for a moment how *you* might implement run-time memory
: >protection under MS-DOS before you ask the compiler to.  Under many
: >versions of Unix it's a simple matter of clustering the string literals
: >and marking that range of memory as write-protected.

: Sorry, implementing run-time memory protection under MS-DOS is way
: beyond my ability to even contemplate, but thanks for asking :-). I
: guess what I thought should happen and believed possible is this. If
: clustering the string literals is a simple matter for Unix then it
: seems to follow that under MS-DOS the string literals could at least
: be recognized as such by the compiler code. Given the ability to
: recognize a string literal it doesn't seem it would be difficult or
: unreasonable to expect the compiler to generate a message (preferably
: an error) if an attempt to modify the string literal is made. After
: all, isn't this an attempt to violate the standard?

Recognizing that an object is a string literal is easy, but generating
an error when it is accessed is not.  For example,

  char *s = "string";
  *s = 'a';

might be caught at compile-time (with quite a bit of extra non-trivial
checking), but:

  char *s = "string";
  char *t = s;
  *t = 'a';

and the like are nightmares to catch at compile-time.  Therefore, these
are generally left to run-time protection, which MS-DOS doesn't have.

[...]
: I know it's my responsibilty to learn the proper use of the language
: and not knowingly violate any of it's provisions.
[...]
: I've placed a
: lot of faith in the compiler checking errors for me and this is one I
: think it should catch.
[...]

The older MS-DOS compilers are pretty rotten when it comes to conformance
to the Standard, actually.  Borland, in particular, introduced things
like 'itoa()' in stdio.h, IIRC, which violates namespace that would
otherwise belong to the user.  It introduced a keyword 'far' which
doesn't even try to look like other C type modifiers.

If you have the spare time, do try writing even a minimalist C
compiler.  It's an extremely interesting exercise, and I'm sure will
answer many of your questions of the form "why doesn't the compiler..".
:)



Thu, 02 Sep 1999 03:00:00 GMT  
 HELP - String Space????


Quote:
> I have the following program:
> #include <stdio.h>
> int main() {
>   char* s = "123 456";
>   s[4]='9';
>   printf("%s", *s);
>   return 0;
> }

> This looks right to me - it should work in my mind - but it doesn't - I
> get a SIGBUS and a wonderful core file out of it instead.  I'm running
> Linux at home and I've also compiled this on the Sparc (running Solaris)
> at school and I get the same {*filter*}y thing.

OK, the best way to understand this is to think about how it would
commonly implemented on a host machine (not necessarily on your
machine; we are speaking in general terms).

Imagine that your program occupies two regions of memory.  One is
reserved for your program, and one is reserved for your data.  Both
are made up of bytes, of course.  A common thing that is done is to
"protect" the memory that the program occupies so that it is read
only.  This is done for two reasons; 1) reliability, because it
prevents a program bug from corrupting the program memory, and 2)
it allows multiple users on a system to share the same copy of the
program.

Now, when you have a string constant like the above, the C standard
states that it cannot be modified.  This means that the compiler
is free to put its strings in the program region, which adds
protection, and also cuts down on the amount of memory each user
needs.  When you try and assign to this memory, you will get an
error, commonly "memory fault" on Unix systems.

Another reason is that it allows the compiler to map common strings
onto the same area of memory.  Imagine if you had,

    ...
    char *s1 = "This is a string";
    char *s2 = "This is a string";
    ...

There is no reason to make these separate strings, so the compiler
can be smart and make the two pointers point to the same region
of memory.

[snip]

Quote:
> I assumed that if something was defined such as the above notation, that
> it was just a shortcut .. so whether I do:

>   void main() {
>     char*s = "123 456";
>   }

> or whether I use:

>   #include <string.h>
>   void main() {
>     char*s;
>     strcpy(s, "123 456");
>   }

Think about a pointer as holding a memory address, which is a
common way pointers are implemented (although, not the only way).
In your first example, you are setting a pointer to the address
of where the sequence of chars '1','2','3',' ','4','5','6','\0'
is located.  In your second example, strcpy copies a null
terminated string located in memory from the second argument
to the memory area pointed to by the first argument.  Since you
are passing an unitialized pointer, it will try and copy the
chars to a random spot in memory.  This is what probably caused
the SIGBUS error.

Hope this helps.

--
=========================================================================|

| "Judge all, and be prepared to be judged by all."                      |
=========================================================================|



Thu, 02 Sep 1999 03:00:00 GMT  
 HELP - String Space????


Quote:
> => char* s = "123 456";

You could change it to:

char s[] = "123 456";

This makes the compiler to create an array exactly big enough to
hold the string (along with the trailing 0 byte) as a normal (ie
read-write) variable.

The earlier remarks about indexing and dereferencing are still
valid, of course.

--




Fri, 03 Sep 1999 03:00:00 GMT  
 
 [ 15 post ] 

 Relevant Pages 

1. Help to trim spaces of a string

2. Need help to trim spaces off a string

3. Using CDaoDatabase with Excel file converts string with only spaces to empty string

4. allocating string space for long decimal

5. Input of a string containing spaces?

6. removing unwanted white space from a string

7. String Data and spaces

8. string space

9. A proposed replacement for gets (was: I/P of a string containing spaces)

10. A proposed replacement for gets (was: Input of a string containing spaces)

11. how to print string with spaces

12. Backslash-space in string literals?

 

 
Powered by phpBB® Forum Software