[comp.lang.c] Malloc Trouble with Large Memory Model

bjm@sabin.UUCP (Brendan J. McMahon) (04/20/89)

We have never had any need for any memory module other than the 
default small.

We are switching to a new machine (intel 386 ) and our database libraries
(informix) only came in the large model.

So all programs that use these have to be compiled with -Ml2 (large model 286). 
(Or do they?)

Jist of a Problem:

struct labelrec{
    int blah;
    .
    .
};
struct labelrec  *lrec[20];

lrec[0]=(struct labelrec *)malloc(sizeof(struct labelrec));

Compile Message:
Warning: cast of int expression to far pointer

Run time problems:

Printf(sizeof(struct labelrec)) = Some huge number 

It should be around 64.

So it looks like it has put the lrec pointers into a seperate data segment,
but the int return value from malloc does not give lrec[0] the
large full address (segment:offset pair) needed to access this data.

I am not familiar with memory modules, so many attempts to throw in
near/far keywords around different definitions did no good.

Thanks for any help!
-- 
Brendan J. McMahon
Sabin Metal Corp. |     Refiners of Precious Metals    | Hardware Trouble?
Scottsville, NY   |  ****** Au  Ag  Pt  Pd  Rh ******  | Give us a call, we'll
716-538-2194      |lazlo!sabin!bjm  || ritcsh!sabin!bjm| melt your trouble away

bjm@sabin.UUCP (Brendan J. McMahon) (04/20/89)

It appears that the strange result I was getting from sizeof is due
to an incompatibility between this release of the  informix database
package and our C compilier.

malloc was not the trouble maker.
-- 
Brendan J. McMahon
Sabin Metal Corp. |     Refiners of Precious Metals    | Hardware Trouble?
Scottsville, NY   |  ****** Au  Ag  Pt  Pd  Rh ******  | Give us a call, we'll
716-538-2194      |lazlo!sabin!bjm  || ritcsh!sabin!bjm| melt your trouble away

kremer@cs.odu.edu (Lloyd Kremer) (04/22/89)

In article <208@sabin.UUCP> bjm@sabin.UUCP (Brendan J. McMahon) writes:

>We have never had any need for any memory module other than the 
>default small.
>We are switching to a new machine (intel 386 ) and our database libraries
>(informix) only came in the large model.
>
>lrec[0]=(struct labelrec *)malloc(sizeof(struct labelrec));
>Compile Message:
>Warning: cast of int expression to far pointer
>Run time problems:
>Printf(sizeof(struct labelrec)) = Some huge number 
>I am not familiar with memory modules, so many attempts to throw in
>near/far keywords around different definitions did no good.


Apparently, code compiled in large model is attempting to use the small model
version of malloc().  Malloc is returning a 2-byte entity which is being
cast unsuccessfully to a 4-byte entity.  You must recompile using the large
model version of malloc() (and all other library functions for that matter).

No amount of casting with the near and far keywords will do any good here.
A small model library routine is not capable of handling 4-byte pointers.
It expects to be passed 2-byte pointers, and will return a 2-byte pointer.

The sizeof() problem probably results from pointer subtraction performed on
a mixture of pointer types (large and small).  Even with implicit or explicit
casting to far *, chaos will result, since the small pointer contains no
valid segment information.

-- 
					Lloyd Kremer
					Brooks Financial Systems
					...!uunet!xanth!brooks!lloyd
					Have terminal...will hack!

root@libove.UUCP (Jay M. Libove) (04/23/89)

From article <208@sabin.UUCP>, by bjm@sabin.UUCP (Brendan J. McMahon):
> We have never had any need for any memory module other than the 
> default small.

I'm _very_ surprised.

> We are switching to a new machine (intel 386 ) and our database libraries
> (informix) only came in the large model.
> So all programs that use these have to be compiled with -Ml2 (large model 286). 
> (Or do they?)

They do. Otherwise the loader can't deal with it. I think that
there may be some way around this, but it is much easier to
simply fix code problems that small model let's you get away
with (I'll explain below) and recompile, than it would be to
munge together different models.

> lrec[0]=(struct labelrec *)malloc(sizeof(struct labelrec));

> Compile Message:
> Warning: cast of int expression to far pointer

What's actually happenning here, most likely, is that nowhere
above the first call to malloc() was malloc() declared as an
extern function that returns type (char *) e.g.

extern char *malloc();

so the compiler is using the implicit int return rule to guess
that malloc() returns an int - which on the 8086 and 80286
compiler is a 16 bit quantity - and you're assigning the return
value of a malloc() call to a pointer - which on the 80286 and
80386 is a 32 bit quantity - and are therefore _losing_ 16
bits of address significance... I'm _really_ surprised that
you didn't get a core dump - on an 80286, you would have
gotten a core dump... my guess is that with the much larger
and better managed memory segments of the 80386, the problem
did not manifest itself as clearly as i would have on the 80286.

> Thanks for any help!
You're welcome.

> Brendan J. McMahon
> Sabin Metal Corp. |     Refiners of Precious Metals    | Hardware Trouble?
> Scottsville, NY   |  ****** Au  Ag  Pt  Pd  Rh ******  | Give us a call, we'll
> 716-538-2194      |lazlo!sabin!bjm  || ritcsh!sabin!bjm| melt your trouble away

------------- 
Jay Libove		jl42@andrew.cmu.edu, libove@cs.cmu.edu,
5731 Centre Ave, Apt 3	gateway.sei.cmu.edu!libove!libove, jl42@andrew.BITnet,
Pittsburgh, PA 15206	psuvax1!pitt!darth!libove!libove,
(412) 362-8983		or uunet!nfsun!libove!libove

dkelly@npiatl.UUCP (Dwight Kelly) (04/25/89)

In article <250@libove.UUCP> root@libove.UUCP (Jay M. Libove) writes:
>                                   I'm _really_ surprised that
>you didn't get a core dump - on an 80286, you would have
>gotten a core dump... my guess is that with the much larger
>and better managed memory segments of the 80386, the problem
>did not manifest itself as clearly as i would have on the 80286.
>

MS-DOS does not core dump.  Only strange things start to happen.
What a great OS!
---
Dwight Kelly            UUCP: gatech!npiatl!dkelly
Director R&D            AT&T: (404) 962-7220
Network Publications, Inc    2 Pamplin Drive     Lawrenceville, GA  30245
             Publisher of "The Real Estate Book" nationwide!

daveh@marob.MASA.COM (Dave Hammond) (04/25/89)

In article <8596@xanth.cs.odu.edu> kremer@cs.odu.edu (Lloyd Kremer) writes:
>In article <208@sabin.UUCP> bjm@sabin.UUCP (Brendan J. McMahon) writes:
>>Compile Message:
>>Warning: cast of int expression to far pointer
>>Run time problems:
>>Printf(sizeof(struct labelrec)) = Some huge number 
>Apparently, code compiled in large model is attempting to use the small model
>version of malloc().  Malloc is returning a 2-byte entity which is being
>cast unsuccessfully to a 4-byte entity.  You must recompile using the large
>model version of malloc() (and all other library functions for that matter).

Using the compiler switch -M2l insures that the compiler uses the large model
library for the standard C routines.  Assuming all of the your modules have
been compiled with -Ml2, there should be no model mismatches.

If you're using an ANSI compiler, be sure the standard C library prototype
header stddef.h is included (for correct malloc prototype), otherwise try
declaring malloc() in the modules which reference it:

char *malloc();

--
Dave Hammond
daveh@marob.masa.com