[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Re: I need help

janus

5/14/2011 6:15:00 PM

Another thing it is likely to print is "SIGSEGV" or "SIGBUS" or
"General Protection Fault" or something along those lines. The
anonymous array created by the string literal is not `const', but
that's just an accident of history. Trying to modify such an array
yields undefined behavior -- and indeed, plenty of compilers will
put the arrays in read-only memory. (This allows them to save space
by allocating just one array to hold both of "over" and "recover".)

I am a bit confused by the above...

Is the correct?

char* string = "NEW";
strcat(string, "Jersey");

If string is in read-only memory, could it still support things like concatenation?

Janus
15 Answers

Dave \Crash\ Dummy

5/14/2011 6:30:00 PM

0


"janus" <emekamicro@gmail.com> schrieb im Newsbeitrag
news:45f62c12-a439-42b7-be27-bab7c954e209@glegroupsg2000goo.googlegroups.com...
....
> Is the correct?
>
> char* string = "NEW";
> strcat(string, "Jersey");
>
> If string is in read-only memory, could it still support things like
> concatenation?
>
> Janus

read-only memory does not support concatenation either. And there is yet
another problem when you code:

char string[] = "NEW";
strcat(string, "Jersey");

You do not reserve space to hold the concatenated string. Here is how you
could do it:

char string[10] = "NEW";
strcat(string, "Jersey");

However strcat has the danger to run out of string size. I always code that:

char string[10] = "NEW";
strncat(string, "Jersey", sizeof(string) - strlen(string) - 1);

or with a macro:

#define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1)
char string[10] = "NEW";
STRNCAT(string, "Jersey");

Keith Thompson

5/14/2011 6:34:00 PM

0

janus <emekamicro@gmail.com> writes:
> Another thing it is likely to print is "SIGSEGV" or "SIGBUS" or
> "General Protection Fault" or something along those lines. The
> anonymous array created by the string literal is not `const', but
> that's just an accident of history. Trying to modify such an array
> yields undefined behavior -- and indeed, plenty of compilers will
> put the arrays in read-only memory. (This allows them to save space
> by allocating just one array to hold both of "over" and "recover".)
>
> I am a bit confused by the above...
>
> Is the correct?
>
> char* string = "NEW";
> strcat(string, "Jersey");
>
> If string is in read-only memory, could it still support things like
> concatenation?

No.

On my system, a program containing those two lines died with a
segmentation fault.

But of course that's not the only possible result. String literals
(more accurately, the static arrays associated with them) aren't
*necessarily* stored in read-only memory. The strcat() call will
attempt to store the 7 characters of "Jersey" (6 plus the trailing
'\0') at locations starting after the 'W' in "NEW". This might
appear to work, if that area of memory happens to be writable
and happens not to be used for anything else. On the other hand,
it could clobber some other variable, or write over some internal
information (such as the function's return address), with arbitrarily
bad results that might not even appear until later.

And the phrase "will attempt" above isn't strictly correct. Since
the behavior is undefined, strcat() could conceivably detect that it
won't be able to write the characters and do something else instead.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Phil Carmody

5/15/2011 10:04:00 AM

0

"Heinrich Wolf" <invalid@invalid.invalid> writes:
> "janus" <emekamicro@gmail.com> schrieb im Newsbeitrag
> news:45f62c12-a439-42b7-be27-bab7c954e209@glegroupsg2000goo.googlegroups.com...
> ...
> > Is the correct?
> >
> > char* string = "NEW";
> > strcat(string, "Jersey");
> >
> > If string is in read-only memory, could it still support things like
> > concatenation?
> >
> > Janus
>
> read-only memory does not support concatenation either. And there is
> yet another problem when you code:
>
> char string[] = "NEW";
> strcat(string, "Jersey");
>
> You do not reserve space to hold the concatenated string. Here is how
> you could do it:
>
> char string[10] = "NEW";
> strcat(string, "Jersey");
>
> However strcat has the danger to run out of string size. I always code that:
>
> char string[10] = "NEW";
> strncat(string, "Jersey", sizeof(string) - strlen(string) - 1);

Why do you want to scan accross "NEW" twice? Once in the strlen, and
once in the strncat.

Phil
--
"At least you know where you are with Microsoft."
"True. I just wish I'd brought a paddle." -- Matthew Vernon

Dave \Crash\ Dummy

5/15/2011 11:19:00 AM

0


"Phil Carmody" <thefatphil_demunged@yahoo.co.uk> schrieb im Newsbeitrag
news:87mxiouvp8.fsf@bazspaz.fatphil.org...
....
> Why do you want to scan accross "NEW" twice? Once in the strlen, and
> once in the strncat.

I know that I could save some microseconds with

size_t l = strlen(a);
strncat(a + l, b, sizeof(a) - l - 1);

but STRNCAT has done a good job many years and is easy to read.

Eric Sosman

5/15/2011 11:59:00 AM

0

On 5/14/2011 2:15 PM, janus wrote:
> Another thing it is likely to print is "SIGSEGV" or "SIGBUS" or
> "General Protection Fault" or something along those lines. The
> anonymous array created by the string literal is not `const', but
> that's just an accident of history. Trying to modify such an array
> yields undefined behavior -- and indeed, plenty of compilers will
> put the arrays in read-only memory. (This allows them to save space
> by allocating just one array to hold both of "over" and "recover".)
>
> I am a bit confused by the above...

It is customary to mark the material you quote, making it
distinguishable from material of your own authorship. See those
greater-than signs at the left margin? Most news clients or mail
clients will insert them for you.

It is also customary to attribute the quoted material to its
author (or authors), so that readers aren't misled into thinking
its your own. See that "On...janus wrote:" line at the top?
Again, most news clients or mail clients will insert such lines
for you.

To use the medium effectively, first learn to use the medium.

> Is the correct?
>
> char* string = "NEW";
> strcat(string, "Jersey");

Undefined behavior.

> If string is in read-only memory, could it still support things like concatenation?

No.

Nor should it. Think of it this way: A string literal (when
used this way) is notionally a constant, much like 42 or 3.14. If
you start modifying constants, things will become very confusing
very rapidly:

int i = 6;
6 *= 7; /* not legal; just imagine */
int j = 6; /* does j have the value forty-two? */

Similarly with string constants: By concatenating to a string (or
by changing one or more of its existing characters), you change
the value of that string. So:

char *message = "Hello, world!";
strcpy(message, "Go to Hell!"); /* not legal; just imagine */
puts(message); /* friendly, or confrontational? */

You don't (or shouldn't) want to change a constant, and C doesn't
promise that an attempt to do so will succeed. (Doesn't promise
anything at all about what will happen, actually.)

--
Eric Sosman
esosman@ieee-dot-org.invalid

Eric Sosman

5/15/2011 12:13:00 PM

0

On 5/14/2011 2:29 PM, Heinrich Wolf wrote:
>[...]
> However strcat has the danger to run out of string size. I always code
> that:
>
> char string[10] = "NEW";
> strncat(string, "Jersey", sizeof(string) - strlen(string) - 1);
>
> or with a macro:
>
> #define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1)
> char string[10] = "NEW";
> STRNCAT(string, "Jersey");

If you like this sort of thing, so be it -- I'm not convinced
there's much value in using training wheels, but tastes vary.

However, you ought to mention that this STRNCAT macro relies
on the pre-existing '\0' at the end of the output array. If
string[9] were '?' instead of '\0', STRNCAT would run happily but
leave you with a non-terminated string, just waiting to cause
unpleasant surprises later.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Dave \Crash\ Dummy

5/15/2011 12:30:00 PM

0


"Eric Sosman" <esosman@ieee-dot-org.invalid> schrieb im Newsbeitrag
news:iqog3e$27h$1@dont-email.me...
....
> However, you ought to mention that this STRNCAT macro relies
> on the pre-existing '\0' at the end of the output array. If
> string[9] were '?' instead of '\0', STRNCAT would run happily but
> leave you with a non-terminated string, just waiting to cause
> unpleasant surprises later.
....
No! strncat guarantees to append a terminating '\0' character, even if it
needs to truncate the source string. That is the difference to strncpy. You
do net need to memset(output, 0 sizeof(output)); The only prerequisite is,
that output is terminated by a single '\0' before. But that is the same with
strcat.

Eric Sosman

5/15/2011 12:46:00 PM

0

On 5/15/2011 8:30 AM, Heinrich Wolf wrote:
>
> "Eric Sosman" <esosman@ieee-dot-org.invalid> schrieb im Newsbeitrag
> news:iqog3e$27h$1@dont-email.me...
> ...
>> However, you ought to mention that this STRNCAT macro relies
>> on the pre-existing '\0' at the end of the output array. If
>> string[9] were '?' instead of '\0', STRNCAT would run happily but
>> leave you with a non-terminated string, just waiting to cause
>> unpleasant surprises later.
> ...
> No! strncat guarantees to append a terminating '\0' character, even if
> it needs to truncate the source string. That is the difference to
> strncpy. You do net need to memset(output, 0 sizeof(output)); The only
> prerequisite is, that output is terminated by a single '\0' before. But
> that is the same with strcat.

My apologies: I confused `strncat' with `strncpy'.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Phil Carmody

5/16/2011 1:32:00 AM

0

"Heinrich Wolf" <invalid@invalid.invalid> writes:

> "Phil Carmody" <thefatphil_demunged@yahoo.co.uk> schrieb im
> Newsbeitrag news:87mxiouvp8.fsf@bazspaz.fatphil.org...
> ...
> > Why do you want to scan accross "NEW" twice? Once in the strlen, and
> > once in the strncat.
>
> I know that I could save some microseconds

You knew you always knew the ratio of the length of the left
string compared to the right string? Wow, you're a lucky man.
I wish I could be so certain that arbitrary input was so
predictable.

Phil
--
"At least you know where you are with Microsoft."
"True. I just wish I'd brought a paddle." -- Matthew Vernon

Phil Carmody

5/16/2011 1:34:00 AM

0

Eric Sosman <esosman@ieee-dot-org.invalid> writes:

> On 5/15/2011 8:30 AM, Heinrich Wolf wrote:
> >
> > "Eric Sosman" <esosman@ieee-dot-org.invalid> schrieb im Newsbeitrag
> > news:iqog3e$27h$1@dont-email.me...
> > ...
> >> However, you ought to mention that this STRNCAT macro relies
> >> on the pre-existing '\0' at the end of the output array. If
> >> string[9] were '?' instead of '\0', STRNCAT would run happily but
> >> leave you with a non-terminated string, just waiting to cause
> >> unpleasant surprises later.
> > ...
> > No! strncat guarantees to append a terminating '\0' character, even if
> > it needs to truncate the source string. That is the difference to
> > strncpy. You do net need to memset(output, 0 sizeof(output)); The only
> > prerequisite is, that output is terminated by a single '\0' before. But
> > that is the same with strcat.
>
> My apologies: I confused `strncat' with `strncpy'.

Votes for abolishing srtncat?

1 here; I trust the above is enough of a reason to come on board, and from
what Heinrich has posted, hopefully there's a 3rd vote too.

Phil
--
"At least you know where you are with Microsoft."
"True. I just wish I'd brought a paddle." -- Matthew Vernon