[comp.sys.ibm.pc] Turbo C memset problem

nwc@cunixc.columbia.edu (Nick Christopher) (11/13/87)

I had code that was very happy in the small model in which I blanked and
character array using memset as follows:

char string[80]

memset(string,NULL,80);

however when I moved to large model this no longer worked, it began to have
the exact same 3 garbage characters at the begining of string.  Is this the 
fault  of my format or the memset's fault.

/nwc
-- 
		"I am the Lorvax. I speak for the machines."
______________________________________________________________________________
nwc%cunixc@columbia, columbia!cunixc!nwc  BITNET: nwcus@cuvma 
            USENET: topaz!columbia!cunixc!nwc

kgdykes@orchid.UUCP (11/13/87)

In article <238@cunixc.columbia.edu> nwc@cunixc.columbia.edu (Nick Christopher) writes:
>
>I had code that was very happy in the small model in which I blanked and
>character array using memset as follows:
>
>char string[80]
>
>memset(string,NULL,80);
>
>however when I moved to large model this no longer worked, it began to have
>the exact same 3 garbage characters at the begining of string.  Is this the 
>fault  of my format or the memset's fault.
>
>nwc%cunixc@columbia, columbia!cunixc!nwc  BITNET: nwcus@cuvma 

Probably your fault.
 NULL is actually a POINTER, not a zero-value.
 most <stdio.h> or <stddef.h> would define it as either (void *)0
 or (char *)0
 but they are also free on some machines to use MAGIC VALUES.
In your situation, it worked in the normal/small model
because a null-small pointer happens to be a value of 0 with the sizeof(int)
But when you go to large model, the NULL pointer includes segment-info or
something (the same garbage chars you see), and also the size is no longer the
sizeof(int) but probably twice the size. (1word for segment, 1 word for offset)
If you checked futher, you would find that you werent getting 80 bytes
processed either.
A hypothetical stack frame for the working (small) model:
 would be: memset(ptr,NULL,80) -->   | 1word-ptr | 1word-ptr-of-0 | 1word=80 |
For the large model:
 memset(ptr,NULL,80) --> |2wd-ptr(seg+offset)|2wd-ptr(seg+offset)=NULL|1wd=80|
 
then the code of memset assumes the 2nd arg is only a char-value (int actually)
 and scoops up the first part of the far-ptr-NULL as the "value" and
the second part of the far-ptr-NULL as the 3rd-argument "length" to process.
And the 80-value is simply not noticed.
What you need to say is:   memset(ptr, 0, 80);
and only use NULL for POINTER usage, not CHAR or INT.
In the modern age we are not allowed to assume that NULL equals ZERO
The above theories do not come from DOS/turbid experience,
 but my general C compiler viewpoint.
 So i will protect myself by attaching the word "probably" to
 the above statements.
What you should really say to work is:  memset(ptr, 0, 80);
   -Ken
-- 
          - Ken Dykes,   Software Development Group, U.of.Waterloo
              kgdykes@watmath.uucp     kgdykes@water.bitnet
              kgdykes@waterloo.csnet

darrylo@hpsrlc.HP.COM (Darryl Okahata) (11/15/87)

In comp.sys.ibm.pc, nwc@cunixc.columbia.edu (Nick Christopher) writes:

> I had code that was very happy in the small model in which I blanked and
> character array using memset as follows:
> 
> char string[80]
> 
> memset(string,NULL,80);
> 
> however when I moved to large model this no longer worked, it began to have
> the exact same 3 garbage characters at the begining of string.  Is this the 
> fault  of my format or the memset's fault.
> 
> /nwc
> -- 
> 		"I am the Lorvax. I speak for the machines."
> ______________________________________________________________________________
> nwc%cunixc@columbia, columbia!cunixc!nwc  BITNET: nwcus@cuvma 
>             USENET: topaz!columbia!cunixc!nwc
> ----------

     The second argument to memset() is supposed to be a character: in
place of a character, you have "NULL" which typically represents a NULL
pointer (strictly speaking, a null pointer should be "(char *) NULL", not
just "NULL" -- but that's another story).  To fix your problem, use:

     memset(string, '\0', 80);

Your problem stems from the use of "NULL" instead of a character; in the
small memory model, the use of "NULL" pushes a word (16 bits) onto the
stack for the second argument, whereas, in the large memory model, two
words, instead of just one, are pushed on the stack.  As a result, the
stack was misaligned, and memset() could not properly access its arguments.

     -- Darryl Okahata
	{hplabs!hpccc!, hpfcla!} hpsrla!darrylo
	CompuServe: 75206,3074

Disclaimer: the above is the author's personal opinion and is not the
opinion or policy of his employer or of the little green men that
have been following him all day.