[comp.lang.c] malloc vs calloc and invalid pointers

chris@mimsy.UUCP (Chris Torek) (09/25/88)

In article <706.2339B3DF@stjhmc.fidonet.org>
will.summers@p6.f18.n114.z1.fidonet.org (will summers) writes:
>This got me thinking about a subtle dpANS wording difference:
>
>    struct _whatever *pstruct;
>
>    pstruct = (struct _whatever *) malloc (n * sizeof(struct _whatever));
>
>is pstruct[n-1] or pstruct+(n-1) -guaranteed- to be allowed on
>-all- dpANS conformant installations?

Assuming that malloc did not return NULL, yes.  If it did not you would
not have allocated at least n*sizeof(struct _whatever) bytes.
(Incidentally, `_' marks a reserved name space.)  Rephrasing the
question as `is &pstruct[n] legally computable', the answer is still
yes.

>I guess it comes down to this: does dpANS -guarantee- an object is
>divisable into sub-objects following Chris Torek's "locally
>flat" paradigm, and that pointers produced by arithmetic on 
>pointers to the sub-objects will be valid.

A `malloc'ed object, yes; at least, that was certainly the intention.

>Simply stated, does dpANS wording imply any difference between
>calloc (n, size) and  malloc (n*size) ?

Other than that calloc fills the allocated memory with zero bytes,
there is no guaranteed difference.  It is possible that one or the
other might be preferable on some architecture (calloc is often just
malloc+memset in disguise, but on some machine calloc might be able to
use less space, since it gets more information), but there is no
predicting which is best where, and either is correct.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

djones@megatest.UUCP (Dave Jones) (09/27/88)

From article <13731@mimsy.UUCP>, by chris@mimsy.UUCP (Chris Torek):
> In article <706.2339B3DF@stjhmc.fidonet.org>
> will.summers@p6.f18.n114.z1.fidonet.org (will summers) writes:
>>This got me thinking about a subtle dpANS wording difference:
>>
>>    struct _whatever *pstruct;
>>
>>    pstruct = (struct _whatever *) malloc (n * sizeof(struct _whatever));
>>
>>is pstruct[n-1] or pstruct+(n-1) -guaranteed- to be allowed on
>>-all- dpANS conformant installations?
> 
> Assuming that malloc did not return NULL, yes.

Another way of stating the question is, "Is sizeof(foo) constrained to
be a multiple of the alignment of foo?"  

(I have another question at the bottom of this posting.)

The only copy I have of the proposed ANSII C standard is a pretty early
one.  It says, "When applied to a structure or union object, the result
is the total number of bytes in the object considered as a member of an
array..."  That indicates that the code above is okay (provided that
your compiler is ANSII C.)

When I wrote a storage allocator a while back, I was not quite willing
to believe the guarantee, so I defined a structure, 
"struct heap_unit" which could be redefined on various machines if 
necessary.  All memory  allocations were done in multiples of 
sizeof(heap_unit).  The first, and so far only, implementation 
(for Sun3) was as follows:

typedef struct heap_unit
{ struct heap_unit* next; }
Heap_unit;

The "next" field is used to link free-lists together. 

...

Now for the other question: Is it guaranteed that the actual memory
allocated (static, automatic, or malloc) for a variable foo is always
at least sizeof(foo)?  It would seem that such should be the case,
but I can't find it stated explicitly in my old draft.  (I am completely
uninterested in the moral and socioethical considerations of the following
code.)

bar()
{
  char a;
  struct something foo;
  char z;

  a = 'a';
  z = 'z';

  /* Might the following "step on" char a or char z? */

  bzero(&foo, sizeof(foo));

}

Occording to the standard, sizeof(foo) returns the size which would
be allocated for a struct something in an array. Will this much
necessarily be allocated for foo on the stack, insulating it from
char a and char z?

gwyn@smoke.ARPA (Doug Gwyn ) (10/03/88)

In article <827@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes:
>Now for the other question: Is it guaranteed that the actual memory
>allocated (static, automatic, or malloc) for a variable foo is always
>at least sizeof(foo)?

No, under some circumstances an attempt to access some bytes of the
virtual object "foo" might fail.  For example, if "foo" is a structure
with a hole at the end.

>  /* Might the following "step on" char a or char z? */

No, the objects are non-overlapping as a consequence of several
constraints within the dpANS.

djones@megatest.UUCP (Dave Jones) (10/04/88)

From article <8593@smoke.ARPA>, by gwyn@smoke.ARPA (Doug Gwyn ):
> In article <827@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes:
>>Now for the other question: Is it guaranteed that the actual memory
>>allocated (static, automatic, or malloc) for a variable foo is always
>>at least sizeof(foo)?
> 
> No, under some circumstances an attempt to access some bytes of the
> virtual object "foo" might fail.  For example, if "foo" is a structure
> with a hole at the end.
> 
>>  /* Might the following "step on" char a or char z? */

   It would have been nice if you quoted the code.
> 
> No, the objects are non-overlapping as a consequence of several
> constraints within the dpANS.


I don't know if I asked the question well enough.

typedef struct
{ long number;
  char ch;
}foo;

My old spec says that "sizeof(foo)" returns a number which will
do for allocation of an array of fooes.  In other words, sizeof(foo)
must be a multiple of the alignment-number for foo.  

Let's assume that our machine requires that longs be aligned on
even word boundaries, and that long is four bytes.  Then sizeof(foo)
will probably be 6, although according to the spec, it could be eight,
or ten or twelve...  The actual memory allocated for each cell in the 
array will be sizeof(foo).

The question is whether or not the compiler is bound by this 
same restriction in allocating static and automatic foos.

Suppose for example you declare the following:

foo bar;
char ch2;

Since the alignment number for a char is likely one, an overeager
compiler might allocate only five bytes for bar, leaving ch2 on
an odd byte boundary.  Now the following code will fail:

{ 
  ch2 = 'z';
  bzero(&bar, sizeof(foo));
  putchar(ch2);
}

I have seen plenty of code like this, and I think I could be
pretty sympathetic with a beginner who fell into the trap. I would
prefer that the spec require that the above code be safe.  Does it?

gwyn@smoke.ARPA (Doug Gwyn ) (10/05/88)

In article <854@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes:
>I would prefer that the spec require that the above code be safe.  Does it?

Yes.