[comp.lang.c] Indefinite-length array as member of struct; sizeof

ari@eleazar.dartmouth.edu (Ari Halberstadt) (07/18/89)

I sent the following article, but it seems to have arrived without its
body [probably would have forgotten its head if it wasn't attached :-)].
I'm still new to the news networks, so I hope it doesn't appear twice.
The article follows:

In article <821@fozzy.UUCP> ellis@fozzy.UUCP (Randy Ellis) writes:
>In article <7360@c3pe.UUCP>, charles@c3pe.UUCP (Charles Green) writes:
>> When I know how long the string is I'm pushing onto the stack, I say:
>> 	nodeptr = malloc(strlen(data)+5);
>> to cover the struct node* and terminating NULL, and then simply
>> 	strcpy(nodeptr->string, data);
>
>Does this fit your needs?  Change string into a char pointer, then allocate
>dynamic memory for the string and save the pointer into nodeptr->string.
>	nodeptr = malloc(sizeof(struct node));
>	nodeptr->string = malloc(strlen(data)+1);
>	strcpy(nodeptr->string,data);

The sollution given by Randy Ellis is incomplete. Specifically, it omits
a type cast from type "char *" to type "struct node *". The correct line
should read:
	nodeptr = (struct node *) malloc(sizeof(struct node));

I also have a question about memory allocation. Are characters guaranteed
to be only one memory address long? This is very important in expressions
such as:
	nodeptr->string = malloc(strlen(data)+1);
Should the above line really be written as:
	nodeptr->string = malloc( (strlen(data)+1) * sizeof(char) );
I have seen the latter in several books, but it really wasn't clear from the
examples what should be done.

If possible, please include a source (e.g., book name) with your response.
Ari Halberstadt '91, "Long live short signatures"

cc100aa@prism.gatech.EDU (Ray Spalding) (07/19/89)

In article <14474@dartvax.Dartmouth.EDU> ari@eleazar.dartmouth.edu (Ari Halberstadt) writes:
>I also have a question about memory allocation. Are characters guaranteed
>to be only one memory address long? This is very important in expressions
>such as:
>	nodeptr->string = malloc(strlen(data)+1);
>Should the above line really be written as:
>	nodeptr->string = malloc( (strlen(data)+1) * sizeof(char) );
>I have seen the latter in several books, but it really wasn't clear from the
>examples what should be done.

According to the pANS in K&R II section A7.4.8: "the _sizeof_ operator
yields the number of bytes required to store an object...When _sizeof_ is
applied to a _char_, the result is 1".  And, in B5: "_malloc_ returns a
pointer to space for an object of size _size_" (by which I infer they
mean "size" in the sense of the _sizeof_ operator).

So, either "malloc" above will work (in a correct implementation),
and the choice is a matter of style only.

But, it has nothing to do with the memory addressing scheme of the
machine you're running on; if a byte is not addressable as a unit,
the implementation must allow for that behind the scenes.
-- 
Ray Spalding
Georgia Institute of Technology, Atlanta Georgia, 30332
uucp:     ...!{allegra,amd,hplabs,ut-ngp}!gatech!prism!cc100aa
Internet: cc100aa@prism.gatech.edu

kemnitz@mitisft.Convergent.COM (Gregory Kemnitz) (07/19/89)

In article <14474@dartvax.Dartmouth.EDU| ari@eleazar.dartmouth.edu (Ari Halberstadt) writes:
|I sent the following article, but it seems to have arrived without its
|body [probably would have forgotten its head if it wasn't attached :-)].
|I'm still new to the news networks, so I hope it doesn't appear twice.
|The article follows:
|
|In article <821@fozzy.UUCP> ellis@fozzy.UUCP (Randy Ellis) writes:
|>In article <7360@c3pe.UUCP>, charles@c3pe.UUCP (Charles Green) writes:
|>> When I know how long the string is I'm pushing onto the stack, I say:
|>> 	nodeptr = malloc(strlen(data)+5);
|>> to cover the struct node* and terminating NULL, and then simply
|>> 	strcpy(nodeptr->string, data);
|>
|>Does this fit your needs?  Change string into a char pointer, then allocate
|>dynamic memory for the string and save the pointer into nodeptr->string.
|>	nodeptr = malloc(sizeof(struct node));
|>	nodeptr->string = malloc(strlen(data)+1);
|>	strcpy(nodeptr->string,data);
|
|The sollution given by Randy Ellis is incomplete. Specifically, it omits
|a type cast from type "char *" to type "struct node *". The correct line
|should read:
|	nodeptr = (struct node *) malloc(sizeof(struct node));
|
|I also have a question about memory allocation. Are characters guaranteed
|to be only one memory address long? This is very important in expressions
|such as:
|	nodeptr->string = malloc(strlen(data)+1);
|Should the above line really be written as:
|	nodeptr->string = malloc( (strlen(data)+1) * sizeof(char) );
|I have seen the latter in several books, but it really wasn't clear from the
|examples what should be done.
|

On page 188 in K & R (First Edition):

      The "sizeof" operator yields the size, in bytes, of its operand.  (A
byte is undefined in the language except in terms of the value of sizeof.
However, in all existing implementations a byte is the space required to
hold a "char".)

In my experience, I have never seen an implementation of C where
sizeof(char) != 1.  (Is there any out there????)  However, I have seen many
where a "byte" is not eight bits, like the Unisys 1100 and the Honeywell 6000
computers (both extremely old architectures).  Since I have not used an ANSI
C compiler, I don't know what ANSI says about sizeof(char), but if it is not
1 the ANSI committee should all be fired :-).

The only other size definition I have seen (this has been talked about at
length on another thread) is

sizeof char <= sizeof short <= sizeof int <= sizeof long

|If possible, please include a source (e.g., book name) with your response.
|Ari Halberstadt '91, "Long live short signatures"

----------------------------------+--------------------------------------
Greg Kemnitz                      | Software without hardware is an idea.
kemnitz@Convergent.COM            | Hardware without software is a space heater.
				  |
                                  | --Unknown author

gwyn@smoke.BRL.MIL (Doug Gwyn) (07/19/89)

In article <786@mitisft.Convergent.COM> kemnitz@mitisft.UUCP (Greg Kemnitz) writes:
>Since I have not used an ANSI C compiler, I don't know what ANSI says about
>sizeof(char), but if it is not 1 the ANSI committee should all be fired :-).

The proposed Standard does require that sizeof(char)==1.  Good arguments
can be (and were) made against this, but X3J11 decided that too many
existing applications had been relying on this property (which had never
previously been guaranteed, but happened to almost universally be the
case).  If the Committee had bought into the notion of "short char" for
byte-sized objects, then it would have been essential to not insist on
sizeof(char)==1.  However, instead they settled on the "wide character"
approach, which was closer to what vendors had already been attempting
to do to support international character sets.  Thus, "char" and byte
are essentially synonymous in Standard C.

>The only other size definition I have seen (this has been talked about at
>length on another thread) is
>sizeof char <= sizeof short <= sizeof int <= sizeof long

The proposed Standard also specifies minimum sizes (in terms of the minimum
range of representable values) for each of these types and their unsigned
counterparts.  It boils down to:
	char: at least 8 bits
	short: at least 16 bits
	int: at least 16 bits
	long: at least 32 bits

There are similar, although more involved, requirements for floating-point
representations.