Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > which is the better way to declare dynamic single dimension array inside struct

Reply
Thread Tools

which is the better way to declare dynamic single dimension array inside struct

 
 
Geetesh
Guest
Posts: n/a
 
      02-27-2004
Recently i saw a code in which there was a structer defination similar
as bellow:
struct foo
{
int dummy1;
int dummy2;
int last[1]
};
In application the above array is always allocated at runtime using
malloc.In this last member of the structer "int last[1]" is not
actually used as array with single element but when alloacting space
for struct foo extra memory is allocated and last is used as array
with more then one element. my question is what are the advantages of
using the above defination instead of the shown below.
struct foo
{
int dummy1;
int dummy2;
int *last;
};
The only advantage i can think of is that we will have to call single
malloc in first declaration and two malloc in second declaration and
also that in first declaration all the memeory allocated will be
contigous which may lead to less framgmentation and better cache
utilization. My question is does using first defination for accessing
of elements faster when compared to second. If yes why?
Thanks in advance.
 
Reply With Quote
 
 
 
 
Jack Klein
Guest
Posts: n/a
 
      02-27-2004
On 26 Feb 2004 21:45:07 -0800, http://www.velocityreviews.com/forums/(E-Mail Removed) (Geetesh)
wrote in comp.lang.c:

> Recently i saw a code in which there was a structer defination similar
> as bellow:
> struct foo
> {
> int dummy1;
> int dummy2;
> int last[1]
> };


This causes undefined behavior and is invalid code under all versions
of the C language standard.

> In application the above array is always allocated at runtime using
> malloc.In this last member of the structer "int last[1]" is not
> actually used as array with single element but when alloacting space
> for struct foo extra memory is allocated and last is used as array
> with more then one element. my question is what are the advantages of
> using the above defination instead of the shown below.


The advantages are that some programmers in any language are hot-shots
who think they know everything and happen on a trick that might work
with their particular compiler and think clever trickery proves that
they are good programmers.

> struct foo
> {
> int dummy1;
> int dummy2;
> int *last;
> };
> The only advantage i can think of is that we will have to call single
> malloc in first declaration and two malloc in second declaration and
> also that in first declaration all the memeory allocated will be
> contigous which may lead to less framgmentation and better cache
> utilization. My question is does using first defination for accessing
> of elements faster when compared to second. If yes why?
> Thanks in advance.


You can still do a single malloc allocation:

foo *fp = malloc(sizeof *foo + how_many_characters_i_want);

/* error checking omitted */

fp->last = (char *)fp + sizeof *fp;

As to "faster", that doesn't apply when you are talking about illegal
code that produces undefined behavior.

Even when comparing two different legal methods of doing something,
the C standard does not specify the relative performance of anything.
The answer could be exactly opposite from one compiler to another.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
 
Reply With Quote
 
 
 
 
Jack Klein
Guest
Posts: n/a
 
      02-27-2004
On 26 Feb 2004 21:45:07 -0800, (E-Mail Removed) (Geetesh)
wrote in comp.lang.c:

> Recently i saw a code in which there was a structer defination similar
> as bellow:
> struct foo
> {
> int dummy1;
> int dummy2;
> int last[1]
> };


This causes undefined behavior and is invalid code under all versions
of the C language standard.

> In application the above array is always allocated at runtime using
> malloc.In this last member of the structer "int last[1]" is not
> actually used as array with single element but when alloacting space
> for struct foo extra memory is allocated and last is used as array
> with more then one element. my question is what are the advantages of
> using the above defination instead of the shown below.


The advantages are that some programmers in any language are hot-shots
who think they know everything and happen on a trick that might work
with their particular compiler and think clever trickery proves that
they are good programmers.

> struct foo
> {
> int dummy1;
> int dummy2;
> int *last;
> };
> The only advantage i can think of is that we will have to call single
> malloc in first declaration and two malloc in second declaration and
> also that in first declaration all the memeory allocated will be
> contigous which may lead to less framgmentation and better cache
> utilization. My question is does using first defination for accessing
> of elements faster when compared to second. If yes why?
> Thanks in advance.


You can still do a single malloc allocation:

foo *fp = malloc(sizeof *foo + how_many_characters_i_want);

/* error checking omitted */

fp->last = (char *)fp + sizeof *fp;

As to "faster", that doesn't apply when you are talking about illegal
code that produces undefined behavior.

Even when comparing two different legal methods of doing something,
the C standard does not specify the relative performance of anything.
The answer could be exactly opposite from one compiler to another.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
 
Reply With Quote
 
Nejat AYDIN
Guest
Posts: n/a
 
      02-27-2004
Jack Klein wrote:
>

[...]
> > struct foo
> > {
> > int dummy1;
> > int dummy2;
> > int *last;
> > };

[...]
> You can still do a single malloc allocation:
>
> foo *fp = malloc(sizeof *foo + how_many_characters_i_want);

^^^ ^^^^
struct foo *fp = malloc(sizeof *fp + how_many_characters_i_want);
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      02-27-2004
Jack Klein <(E-Mail Removed)> wrote:

> On 26 Feb 2004 21:45:07 -0800, (E-Mail Removed) (Geetesh)
> wrote in comp.lang.c:
>
> > struct foo
> > {
> > int dummy1;
> > int dummy2;
> > int *last;
> > };
> > The only advantage i can think of is that we will have to call single
> > malloc in first declaration and two malloc in second declaration

>
> You can still do a single malloc allocation:
>
> foo *fp = malloc(sizeof *foo + how_many_characters_i_want);


Um... sizeof *type?

> /* error checking omitted */
>
> fp->last = (char *)fp + sizeof *fp;


Mind you, that only works with characters; the resulting space is not
guaranteed to be properly aligned for other types. With a bit of trouble
this should be solvable; for example, I think that

struct foo {
float bar;
long baz;
mytype *ptr;
mytype dummy; /* Really _is_ a dummy, for alignment only. */
}
struct foo *fooptr=malloc(sizeof *fooptr +
desired_number_of_objects_of_type_mytype);
fooptr->ptr=(char *)fp + sizeof *fooptr - sizeof *(fooptr->ptr);

should work no matter what mytype is. Note that the dummy object should
be of the base type of the pointer for this trick to work, and that it's
still a dirty piece of code and I give no guarantees; I wouldn't use
this myself. The code with two malloc()s is clearer and cleaner.

Richard
 
Reply With Quote
 
The Real OS/2 Guy
Guest
Posts: n/a
 
      02-27-2004
On Fri, 27 Feb 2004 05:45:07 UTC, (E-Mail Removed) (Geetesh)
wrote:

> Recently i saw a code in which there was a structer defination similar
> as bellow:
> struct foo
> {
> int dummy1;
> int dummy2;
> int last[1]
> };
> In application the above array is always allocated at runtime using
> malloc.In this last member of the structer "int last[1]" is not
> actually used as array with single element but when alloacting space
> for struct foo extra memory is allocated and last is used as array
> with more then one element. my question is what are the advantages of
> using the above defination instead of the shown below.
> struct foo
> {
> int dummy1;
> int dummy2;
> int *last;
> };
> The only advantage i can think of is that we will have to call single
> malloc in first declaration and two malloc in second declaration and
> also that in first declaration all the memeory allocated will be
> contigous which may lead to less framgmentation and better cache
> utilization. My question is does using first defination for accessing
> of elements faster when compared to second. If yes why?
> Thanks in advance.


It save memory. At lest the amount of memory a pointer costs.
It saves time as not every time are 2 malloc() required to fill a
whole struct.

No, it is NOT undefined behavior as Jack Klein says. But it is
implementation defined.

Look at the APIs of your OS. The chance is high that there is at least
one or more APIs who deliver or receive such kind of structs.


--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

 
Reply With Quote
 
The Real OS/2 Guy
Guest
Posts: n/a
 
      02-27-2004
On Fri, 27 Feb 2004 06:14:54 UTC, Jack Klein <(E-Mail Removed)>
wrote:

> On 26 Feb 2004 21:45:07 -0800, (E-Mail Removed) (Geetesh)
> wrote in comp.lang.c:
>
> > Recently i saw a code in which there was a structer defination similar
> > as bellow:
> > struct foo
> > {
> > int dummy1;
> > int dummy2;
> > int last[1]
> > };

>
> This causes undefined behavior and is invalid code under all versions
> of the C language standard.


Chapter and verse please in both ANSI C 89 and ANSI C99.

ANSI C 99 allows even <type> last[0] on this place what makes more
clean that this is only a place holder to have a name for the extra
space.

You may still call this as implementation defined - but NOT undefined.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      02-27-2004
"The Real OS/2 Guy" <(E-Mail Removed)> wrote:

> On Fri, 27 Feb 2004 06:14:54 UTC, Jack Klein <(E-Mail Removed)>
> wrote:
>
> > On 26 Feb 2004 21:45:07 -0800, (E-Mail Removed) (Geetesh)
> > wrote in comp.lang.c:
> >
> > > Recently i saw a code in which there was a structer defination similar
> > > as bellow:
> > > struct foo
> > > {
> > > int dummy1;
> > > int dummy2;
> > > int last[1]
> > > };

> >
> > This causes undefined behavior and is invalid code under all versions
> > of the C language standard.

>
> Chapter and verse please in both ANSI C 89 and ANSI C99.


Note: it is not the declaration as such which invokes UB, but its use as
a variable-sized struct. See the original post.

In ISO (not ANSI; neither you nor I are in the United States - what have
we to do with the US Standards Institute?) C99, 6.7.2.1, and note
especially the indication of "undefined behaviour" in example #19. Since
examples aren't normative, see also 6.5.6#8, and note that the result of
adding a pointer and an integer which is larger than the size of that
pointer is not defined, hence remains undefined. (Note also the
equivalence of array subscription and pointer addition, 6.5.2.1).

In C89, see 3.3.6, which defines pointer-integer addition essentially
identically to C99. Since there's no incomplete final array type in C89
structs, you won't find anything interesting in 3.5.2.1

> ANSI C 99 allows even <type> last[0] on this place what makes more
> clean that this is only a place holder to have a name for the extra
> space.


Not quite. It allows an incomplete array - that is, one _without_ a
size, not with size 0 - as the last member of a structure. An array with
size 0 is, AFAICT, simply not allowed; and using an array with size 1 as
if it were an incomplete array is as undefined as in C89.

> You may still call this as implementation defined - but NOT undefined.


It _is_ undefined. Sorry <g>.

Richard
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      02-27-2004
"The Real OS/2 Guy" <(E-Mail Removed)> wrote:

> On Fri, 27 Feb 2004 05:45:07 UTC, (E-Mail Removed) (Geetesh)
> wrote:
>
> > struct foo
> > {
> > int dummy1;
> > int dummy2;
> > int last[1]
> > };
> > In application the above array is always allocated at runtime using
> > malloc.In this last member of the structer "int last[1]" is not
> > actually used as array with single element but when alloacting space
> > for struct foo extra memory is allocated and last is used as array
> > with more then one element.


> No, it is NOT undefined behavior as Jack Klein says. But it is
> implementation defined.


Yes, it is. Pointer addition beyond the end of the array is undefined.

> Look at the APIs of your OS. The chance is high that there is at least
> one or more APIs who deliver or receive such kind of structs.


That some OSes choose to make this kind of undefined behaviour "work"
does not mean that it suddenly is defined.

Richard
 
Reply With Quote
 
The Real OS/2 Guy
Guest
Posts: n/a
 
      02-27-2004
On Fri, 27 Feb 2004 11:11:47 UTC, (E-Mail Removed) (Richard
Bos) wrote:

> "The Real OS/2 Guy" <(E-Mail Removed)> wrote:
>
> > On Fri, 27 Feb 2004 05:45:07 UTC, (E-Mail Removed) (Geetesh)
> > wrote:
> >
> > > struct foo
> > > {
> > > int dummy1;
> > > int dummy2;
> > > int last[1]
> > > };
> > > In application the above array is always allocated at runtime using
> > > malloc.In this last member of the structer "int last[1]" is not
> > > actually used as array with single element but when alloacting space
> > > for struct foo extra memory is allocated and last is used as array
> > > with more then one element.

>
> > No, it is NOT undefined behavior as Jack Klein says. But it is
> > implementation defined.

>
> Yes, it is. Pointer addition beyond the end of the array is undefined.


Sou you says any action int an array allocated with malloc ends up in
undefined behavior.

> > Look at the APIs of your OS. The chance is high that there is at least
> > one or more APIs who deliver or receive such kind of structs.

>
> That some OSes choose to make this kind of undefined behaviour "work"
> does not mean that it suddenly is defined.


You means that

int *p = malloc(4000),

stat *p1 = p + sizeof(stat) * 100;
stat *p2 = p1++;

is undefined behavior? So please, do never use malloc as it results
always in undefined behavior;

When it were really undefined behavior then we had produced 30 millon
lines of code as we have produced in the last yeare to run on 5
different OSes (linux, AIX, HPUX, MAC OS and OS/2 - as the same soure
gets unmodified - but recompiled running on all that mashines.

We should war our customers that theyr code inspections and regression
checks have faild 5 years ago and that all of theyr critical
applications are failing every minutes - even as the production in
theyr time critical environments runs since then without since are
runs well.

You should warn any OS producer that theyr OS will fail always because
they require undefined behavior as all of them have APIs based on that
technique.

I think you should inform yourself what pointer arithmetic can really
do for you - when you knows what you are doing.

Where is undefined behavior here?

struct x {
size_t cb;
struct a *pa;
int val;
unsigned int flags;
char *sa[1000]; /* we need 3 to 999 chars here */
};

struct y {
size_t cb;
struct a *pa;
int val;
unsigned int flags;
char s[1]; /* we have to compile ANSI C 89! */
};


struct x *p1 = malloc(sizeof(struct x) * 1000); /* UB? */
.....
struct y *p2 = malloc(sizeof(struct x) + strlen(data)); /* UB on what?
*/
.....
strcpy(y->s, data); /* UB? on what? */

Show one single ANSI C 89 compiler who will give undefined behavior on
that. I can't find one.

I can see no UB in the code fragments above. But I see that any byte
addresse gets addressed well.

Tell me what is the difference between UB and and implementation
defined. I see there some.

Whenever you allocs memory in the size you needs - not a single byte
less - then you CAN'T get UB when you knows how to hanlde pointer
arithmetic. There is even in struct y not a single byte that is UB
because anything is well, well aligned well addressed.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
a question about 1-dimension and 2-dimension array Luuk C Programming 15 02-11-2010 02:45 AM
Declare a two-dimension array ottawajn C++ 4 12-14-2006 03:02 PM
length of an array in a struct in an array of structs in a struct in an array of structs Tuan Bui Perl Misc 14 07-29-2005 02:39 PM
Typedef A references struct B which references struct A which... DanielEKFA C++ 8 05-16-2005 10:26 AM
newbie question : picture dimension vs print dimension Rene Wong Digital Photography 9 09-30-2003 01:46 AM



Advertisments