Re: Few doubts (wrong behaviour or correct )




Arthur J. O'Dwyer wrote:
On Wed, 11 Oct 2006 temper3243@xxxxxxxxx wrote:


(I cleaned up your code a bit. I hope you don't write code like that
in Real Life.)

#include <stdio.h>
#include <stdlib.h>
typedef struct b {
int b1;
char bc;
} b;

typedef struct a {
char a;
int a1;
b obj[1];
} a;

int main()
{
a *ptr;
ptr = malloc(sizeof(struct a) + 5*sizeof(struct b));
[...]
return 0;
}

well here are a few questions
1) Where does it fail. I mean is there any exception where it willnot
work assuming malloc works fine.

Technically, it doesn't have to work according to any standard, because
you'll be accessing the array 'b' beyond its end. ('b' has one element,
according to its definition, so accessing 'b[1]' is an error.)

In the standard i have seen that last member of structure can have
incomplete type.
What exactly is an incomplete type and if arr[1] is an incomplete type
then isn't this valid. I am confused about this or i must have
misunderstood this.

In practice, this is historically how a lot of things were implemented
in Unix and so on, so many compilers go out of their way to make sure
it works the way you expected.

2) someone told me in C99 we have declar b obj[] , so that it can be
declared at runtime. How do we do that. Do we have to malloc again .
Does this also have unwanted effects.

See http://david.tribble.com/text/cdiffs.htm#C99-fam
You'd write exactly what you already have, except you'd write 'b[]'
instead of 'b[1]'. Since 'b' now no longer has only one element, it's
acceptable, according to the C99 standard, to refer to b[0], b[1], b[2],
and so on.
The only "unwanted effect" of this approach --- and it's a big one ---
is that it won't work on pre-C99 C compilers.

3) Assuming the below code is a hack and it works , how do i make it
work for n objects of type a with each a having k objects of type b.

You don't. You rewrite the code to use a pointer to a separately
malloc'ed array, which is the /real/ portable solution --- it works
in both C90 and C99.

4) is b *ptr instead of b obj[1] a better way. Why should one use b
obj[1] instead of b *ptr.

It is a better way. The "struct hack" is a historical oddity, but
you shouldn't use it in new code just for the sake of using it. Use
the correct, portable method, even if it takes two more lines.

struct a {
char a;
int a1;
b *obj;
};

int main()
{
struct a *ptr = malloc(sizeof *ptr);
if (ptr != NULL)
ptr->obj = malloc(6*sizeof *ptr->obj);
[...]
free(ptr->obj);
free(ptr);
return 0;
}

HTH,
-Arthur

.



Relevant Pages


Loading