delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/07/26/13:00:10

From: Simon <s DOT j DOT harris AT ic DOT ac DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Why so?
Date: Thu, 26 Jul 2001 17:47:19 +0100
Organization: Imperial College
Lines: 85
Message-ID: <3B604997.CF6B6360@ic.ac.uk>
References: <9jp3tu$vb6c$1 AT ID-89475 DOT news DOT dfncis DOT de> <996152804 DOT 153539 AT queeg DOT ludd DOT luth DOT se> <3B602371 DOT 86D2F40E AT falconsoft DOT be>
NNTP-Posting-Host: pegasus.me.ic.ac.uk
Mime-Version: 1.0
X-Trace: jura.cc.ic.ac.uk 996165995 23217 155.198.69.40 (26 Jul 2001 16:46:35 GMT)
X-Complaints-To: usenet AT jura DOT cc DOT ic DOT ac DOT uk
NNTP-Posting-Date: 26 Jul 2001 16:46:35 GMT
X-Mailer: Mozilla 4.7 [en] (Win98; I)
X-Accept-Language: en
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Tim Van Holder wrote:
> 
> > :   str="01234";
> > :   puts(str);
> > :   printf("%s\n",str);
> > :   strcat(str,"567");
> > :   puts(str);
> > :   printf("%s\n",str);
> > :   return 1;
> >
> > : Why this code produces following results?
> > : 01234
> > : 01234
> > : 01234567
> > : 67
> >
> > : Other compilers give me:
> > : 01234
> > : 01234
> > : 01234567
> > : 01234567
> >
> > Only (bad) luck.
> 
> Actually, no - it IS odd.  With the code he posted, if the strcat does
> not cause a segmentation fault, you'd expect the output he posted as
> resulting from other compilers; the relevant snippet is:
> 
> > :   puts(str);
> > :   printf("%s\n",str);
> 
> Regardless of what str points to, neither of these modify str in any
> way, so both should print the same value.  At the very least,
> "012345" should appear; the rest is memory that might have been
> changed, as it does not belong to the string constant.
>

Not so odd if you consider how the constant memory area may be laid out. 
Since the strcat() is concatenating something onto the end of a constant
string, it is possible that the end of the longer string is overwriting
the format specifier in the printf - also a constant string. - i.e.

memory contents at start:

 start of constant string memory area.
 |
 v
 0  1  2  3  4 \0  %  s \n \0
 ^                 ^
 |                 what the format specifier points to in the printf
 what str points to after str="01234"

after the strcat(str,"567"), the memory contents will now be

 0  1  2  3  4  5  6  7 \0
 ^                 ^
 |                 what the format specifier points to in the printf
 what str points to.

Hence when the puts() is called, str will display the 'expected' string.
when printf is called, the format specifier has been overwritten so it
is now effectively

printf("67",str);

so all it will do is print "67" and be left with an excess parameter
on the stack - thus the fault produces two side effects - destroying
the required format specifier and leaving parameters dangling on the
stack. A different compiler with different constant memory layout
may not cause the printf specifier to be overwritten and will give
the 'expected' result - oh the joys of debugging pointer bugs!


Simon.
-- 
--------------------------------------------------------------------------
Dr. Simon J. Harris                        email:  s DOT j DOT harris AT ic DOT ac DOT uk
Mechatronics in Medicine Laboratory,       tel:    0171 589-5111 x 57068
Department of Mechanical Engineering,	   http://www.me.ic.ac.uk/case/mim
Imperial College of Science, Technology and Medicine,
Exhibition Road, London SW7 2BX
--------------------------------------------------------------------------
      Carlton Dramatic Society web site: http://come.to/carltondrama
--------------------------------------------------------------------------

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019