structure and malloc

F

friend.05

typedef struct
{
int a;
int b;
int c;
} ABC;

typedef struct
{
int d;
int e;
int f;
ABC *abc;
} DEF;

Create function should use a single call to malloc to allocate
memoryfor structure DEF and its constituting structure ABC. In other
words, after a call to the CreateDEF() function, the following
statements should be valid and should work without segmentation
violations:

DEF* pDEF = CreateDEF();
pDEF-->abc-->a = 100 ;


DEF *CreateDEF ( void )
{
}

void FreeDEF (ABC *pABC)
{
}
 
D

Default User

friend.05 said:
typedef struct
{
int a;
int b;
int c;
} ABC;

typedef struct
{
int d;
int e;
int f;
ABC *abc;
} DEF;

Create function should use a single call to malloc to allocate
memoryfor structure DEF and its constituting structure ABC. In other
words, after a call to the CreateDEF() function, the following
statements should be valid and should work without segmentation
violations:

DEF* pDEF = CreateDEF();
pDEF-->abc-->a = 100 ;


DEF *CreateDEF ( void )
{
}

void FreeDEF (ABC *pABC)
{
}


Take your best stab at it, in a complete program. Then we'll help. We
don't do homework.




Brian
 
F

friend.05

typedef struct
{
int a;
int b;
int c;
} ABC;

typedef struct
{
int d;
int e;
int f;
ABC *abc;
} DEF;

DEF *CreateDEF (void)
{
DEF strDEF;

strDEF.abc=(ABC *)malloc(sizeof(ABC));
strDEF.abc->a = 10;
printf("%d\n",strDEF.abc->a);
retDEF=&strDEF;
return retDEF;
}

void FreeDEF (ABC *pABC)
{




}

void main()
{
DEF *pdef = CreateDEF();
pdef->d = 7;
printf("%d\n",pdef->d);
pdef->abc->a = 10;
printf("%d\n",pdef->abc->a);
}


But it is giving segmentation fault
 
W

Walter Roberson

DEF *CreateDEF (void)
{
DEF strDEF;

strDEF.abc=(ABC *)malloc(sizeof(ABC));
strDEF.abc->a = 10;
printf("%d\n",strDEF.abc->a);
retDEF=&strDEF;
return retDEF;
}

You can't return a pointer to a local variable (DEF). (Or rather,
you can't do anything with such a pointer once it has been
returned.)

Consider allocating a memory area big enough to hold both
structures.
 
I

Ian Collins

friend.05 wrote:

Please don't top post!
typedef struct
{
int d;
int e;
int f;
ABC *abc;
} DEF;

DEF *CreateDEF (void)
{
DEF strDEF;

strDEF.abc=(ABC *)malloc(sizeof(ABC));

Avoid casting the return of malloc.
strDEF.abc->a = 10;
printf("%d\n",strDEF.abc->a);
retDEF=&strDEF;
return retDEF;

Think about what you are returning, a local variable. What happens to
strDEF after the function returns.

void main()

Don't write this unless you have good grounds to do so. main returns int.
But it is giving segmentation fault
Explained above.
 
D

Default User

friend.05 said:
typedef struct
{
int a;
int b;
int c;
} ABC;

typedef struct
{
int d;
int e;
int f;
ABC *abc;
} DEF;

DEF *CreateDEF (void)
{
DEF strDEF;

strDEF.abc=(ABC *)malloc(sizeof(ABC));
strDEF.abc->a = 10;
printf("%d\n",strDEF.abc->a);
retDEF=&strDEF;
return retDEF;
}

void FreeDEF (ABC *pABC)
{




}

void main()
{
DEF *pdef = CreateDEF();
pdef->d = 7;
printf("%d\n",pdef->d);
pdef->abc->a = 10;
printf("%d\n",pdef->abc->a);
}


But it is giving segmentation fault
 
D

Default User

friend.05 wrote:

Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or:
<http://www.caliburn.nl/topposting.html>

I'll rearrange things.



Add (see below for reason):

#include said:
typedef struct
{
int a;
int b;
int c;
} ABC;

typedef struct
{
int d;
int e;
int f;
ABC *abc;
} DEF;

DEF *CreateDEF (void)
{
DEF strDEF;

strDEF.abc=(ABC *)malloc(sizeof(ABC));

We don't recommend casting the results of malloc(). It can hide a
dangerous problem, that of not including the proper header, which you
did not.
strDEF.abc->a = 10;
printf("%d\n",strDEF.abc->a);
retDEF=&strDEF;
return retDEF;

Returning a pointer to a local variable is not allowed.

Based on the requirements, which are very bad, you'll have to do some
unpleasant stuff. The obvious way is to allocate a chunk of memory
large enough for both structs. Then you set the "ABC" pointer to the
extra memory.

What's troublesome is the alignment issue. The reason you normally use
malloc() and friends is that you get a pointer properly aligned for any
type.

I have a sort of solution that "works" as in doesn't crash on either
VC++ or gcc/Solaris, which both have four-byte ints and struct pointers.

I think it's probably ok. The DEF struct should pad the end to get back
on a good boundary as needed for things like arrays of the structs.

DEF *CreateDEF (void)
{
char *p;
DEF *strDEF;

strDEF = malloc(sizeof(DEF) + sizeof(ABC));
p = (char*)strDEF;
p += sizeof(strDEF);
strDEF->abc = (void*)p;
strDEF->abc->a = 10;
printf("%d\n",strDEF->abc->a);
return strDEF;
}


The gang will gently point out (ouch!!) if I'm totally whacked out on
that. It's best not to do this sort of thing. Why you had a requirement
for a single allocation, I can't fathom.




Brian
 
C

christian.bau

typedef struct
{
int a;
int b;
int c;
} ABC;

typedef struct
{
int d;
int e;
int f;
ABC *abc;
} DEF;

Create function should use a single call to malloc to allocate
memoryfor structure DEF and its constituting structure ABC.

Assuming that this is homework, I would love to see the solution that
your teacher provides. The specification for the FreeDEF function
looks rather bizarre. I think the following should work:

DEF* CreateDEF (void) {
typedef struct { ABC abc; DEF def; } combined;
combined* p = malloc (sizeof (combined));
if (p) { p->def.abc = &p->abc; return &p->def; }
else return NULL;
}

void FreeDEF (ABC* pABC) { free (pABC); }
 
B

Barry Schwarz

friend.05 wrote:

snip

snip

Based on the requirements, which are very bad, you'll have to do some
unpleasant stuff. The obvious way is to allocate a chunk of memory
large enough for both structs. Then you set the "ABC" pointer to the
extra memory.

What's troublesome is the alignment issue. The reason you normally use
malloc() and friends is that you get a pointer properly aligned for any
type.

I have a sort of solution that "works" as in doesn't crash on either
VC++ or gcc/Solaris, which both have four-byte ints and struct pointers.

I think it's probably ok. The DEF struct should pad the end to get back
on a good boundary as needed for things like arrays of the structs.

DEF *CreateDEF (void)
{
char *p;
DEF *strDEF;

strDEF = malloc(sizeof(DEF) + sizeof(ABC));
p = (char*)strDEF;
p += sizeof(strDEF);
strDEF->abc = (void*)p;
strDEF->abc->a = 10;
printf("%d\n",strDEF->abc->a);
return strDEF;
}


The gang will gently point out (ouch!!) if I'm totally whacked out on
that. It's best not to do this sort of thing. Why you had a requirement
for a single allocation, I can't fathom.

The alignment issue can be resolved by declaring a local struct type
which contains both "real" structures, as in
struct mystruct{
DEF x;
ABC y;
};

We know the offset of x is 0 and we can find the offset of y using the
offsetof macro. If you allocate enough space for a struct mystruct
and store the address in DEF* p. You can then safely use
p->abc = (ABC*)((char*)p + offsetof(struct mystruct, y));
to insure that abc points to a valid ABC. Then
p->abc->a = 10;
is safe.


Remove del for email
 
I

Ian Collins

Default said:
friend.05 wrote:

Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or:
<http://www.caliburn.nl/topposting.html>

I'll rearrange things.




Add (see below for reason):



We don't recommend casting the results of malloc(). It can hide a
dangerous problem, that of not including the proper header, which you
did not.


Returning a pointer to a local variable is not allowed.

Based on the requirements, which are very bad, you'll have to do some
unpleasant stuff. The obvious way is to allocate a chunk of memory
large enough for both structs. Then you set the "ABC" pointer to the
extra memory.

What's troublesome is the alignment issue. The reason you normally use
malloc() and friends is that you get a pointer properly aligned for any
type.

I have a sort of solution that "works" as in doesn't crash on either
VC++ or gcc/Solaris, which both have four-byte ints and struct pointers.

I think it's probably ok. The DEF struct should pad the end to get back
on a good boundary as needed for things like arrays of the structs.

DEF *CreateDEF (void)
{
char *p;
DEF *strDEF;

strDEF = malloc(sizeof(DEF) + sizeof(ABC));
p = (char*)strDEF;
p += sizeof(strDEF);
strDEF->abc = (void*)p;

I would prefer a second malloc here, just to be sure of the alignment.
 
I

Ian Collins

Ian said:
I would prefer a second malloc here, just to be sure of the alignment.
Sorry for not trimming before.

The alternative local struct solution may be better than 2 mallocs,
assuming the lifetime of abc is the same as def.
 
D

Default User

Ian said:
Default User wrote:

I would prefer a second malloc here, just to be sure of the alignment.


Absolutely, but the original requirements were:



Brian
 
D

Default User

Barry said:
On 8 May 2007 23:19:49 GMT, "Default User" <[email protected]>
wrote:
The alignment issue can be resolved by declaring a local struct type
which contains both "real" structures, as in
struct mystruct{
DEF x;
ABC y;
};

Oh, that's a pretty slick idea. I didn't think of that, but yeah it
should take care of the situation.



Brian
 
J

Jack Klein

friend.05 wrote:

[snip]
Returning a pointer to a local variable is not allowed.

Absolutely untrue. Of course it can be returned, and in fact it was.

Undefined behavior occurs if one uses the value of that pointer, or
any other pointer that points to memory whose storage duration has
expired.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
D

Default User

Jack said:
friend.05 wrote:
[snip]

Returning a pointer to a local variable is not allowed.

Absolutely untrue. Of course it can be returned, and in fact it was.

Yeah, yeah, after I posted that I knew I should have been more specific.



Brian
 
K

Keith Thompson

Default User said:
Oh, that's a pretty slick idea. I didn't think of that, but yeah it
should take care of the situation.

Yeah, pretty slick. And isn't it nice that the OP didn't have to do
his own homework?
 
I

Ian Collins

Default said:
Absolutely, but the original requirements were:

Now you can see why I used to get marked exam papers back with "real the
whole question" scrawled on them!
 
D

Default User

Keith said:
Yeah, pretty slick. And isn't it nice that the OP didn't have to do
his own homework?

The OP made a stab after prodding, and frankly this was such a poor
assignment that I'm ok with things.



Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top