473,761 Members | 4,739 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Yet another free() question.

I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));

free(ptrToA);
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)? The posts I
have read strongly suggest this will, as probably intended, free the
entire block produced by calloc(), but in those posts it seems
sizeof(Aobj) == N*sizeof(Bobj), i.e. the size of the allocated block is
an integer multiple of the dereferenced type of the pointer to which
the allocated block's void pointer is cast (Don't know how to express
this well). Such would be the case when allocating a single instance
of an object or an array of the same objects on the heap. Just want to
make sure what is done above is safe (assuming the type interpretation
of the allocated block elsewhere is correct.)

Thank you for your time.

Jan 8 '07 #1
19 1511
la*******@gmail .com wrote:
I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));

free(ptrToA);
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)? The posts I
have read strongly suggest this will, as probably intended, free the
entire block produced by calloc(),
Yes , that's what it will do. It is worth noting that if the
calloc succeeded then it allocated memory which is *at
least* as large as sizeof(struct B) , it doesn't have to be
exactly sizeof(struct B).
but in those posts it seems
sizeof(Aobj) == N*sizeof(Bobj), i.e. the size of the allocated block is
an integer multiple of the dereferenced type of the pointer to which
the allocated block's void pointer is cast (Don't know how to express
this well).
I will guess that by "dereferenc ed type of the pointer" you
mean the type of object the pointer points to. In any case
whether sizeof(Aobj) == N*sizeof(Bobj) holds or whether
sizeof(*Aobj) == N*sizeof(*Bobj) holds is irrelevant , the
free() will free all the memory (if any) which was allocated
by calloc.
Such would be the case when allocating a single instance
of an object or an array of the same objects on the heap.
Since the presence of a heap is up to an implementation
it's best not use the term. If you mean memory obtained
through the malloc family of functions then that's what
you should say.

Having said that , which case are you referring to ? The
formula sizeof(Aobj) == N*sizeof(Bobj) you gave mentions
2 different object types.
Just want to
make sure what is done above is safe (assuming the type interpretation
of the allocated block elsewhere is correct.)
I don't know what "the type interpretation of the
allocated block" is. mallocing memory and freeing
it right away is safe but obviously pointless. Whether
your code is safe depends on what's happening between
the calloc() and the free().

Jan 8 '07 #2
la*******@gmail .com writes:
I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));

free(ptrToA);
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)? The posts I
have read strongly suggest this will, as probably intended, free the
entire block produced by calloc(), but in those posts it seems
sizeof(Aobj) == N*sizeof(Bobj), i.e. the size of the allocated block is
an integer multiple of the dereferenced type of the pointer to which
the allocated block's void pointer is cast (Don't know how to express
this well). Such would be the case when allocating a single instance
of an object or an array of the same objects on the heap. Just want to
make sure what is done above is safe (assuming the type interpretation
of the allocated block elsewhere is correct.)
Yes.

The malloc/calloc/realloc/free subsystem does not, and cannot,
keep track of what you do with the newly allocated pointer after
its value is returned to you. Suppose sizeof(struct A) == 10,
and sizeof(struct b) == 20. In your code, calloc (if successful)
simply returns a void* pointer to 20 bytes of newly allocated memory;
it has no idea that the value 20 was computed as "sizeof(str uct B),
or that you then converted the result from void* to struct A*.

When you call free(PtrToA), free() sees only an argument of type
void*, which happens to have the same value as what was returned by
calloc(), so it frees 20 bytes.

The sizeof, the cast, and the assignment are entirely invisible to
calloc() and free(), and cannot affect their behavior. So as far as
calloc() and free() are concerned, your code is equivalent to:

void *ptr = calloc(1, 20);
free(ptr);

Incidentally, the standard doesn't *quite* guarantee that the initial
fields of your struct A and struct B will be laid out consistently,
unless you happen to declare a union of the two types, though it's
difficult to imagine an implementation in which they wouldn't match.
You might consider making the first member of struct B be of type
struct A, rather than duplicating all the fields explicitly; this
would also avoid any errors that might be introduced by writing the
same sequence of member declarations twice,

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 8 '07 #3
Keith Thompson wrote:
Incidentally, the standard doesn't *quite* guarantee that the initial
fields of your struct A and struct B will be laid out consistently,
unless you happen to declare a union of the two types, though it's
difficult to imagine an implementation in which they wouldn't match.
You might consider making the first member of struct B be of type
struct A, rather than duplicating all the fields explicitly; this
would also avoid any errors that might be introduced by writing the
same sequence of member declarations twice,
Since what is returned by calloc() is guaranteed to
be properly alligned for any type I don't see what
might go wrong even in theory. Unless you're saying
that sizeof(struct A) may be larger than sizeof(struct B).

Jan 8 '07 #4
<la*******@gmai l.comwrote in message
news:11******** **************@ 38g2000cwa.goog legroups.com...
>I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));

free(ptrToA);
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)?
malloc(), calloc(), and free() are block-oriented only. They operate only
in terms of a starting address and a length. There is no type information
involved.

The code in calloc() has no way to determine what calculations went into the
parameters it was passed. They are just integers.

The whole block gets free()'d.
Jan 8 '07 #5

<la*******@gmai l.comwrote in message
news:11******** **************@ 38g2000cwa.goog legroups.com...
>I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));

free(ptrToA);
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)?
It will free the entire block that was allocated.
The signature of free is
void free( void *ptr )
It knows only that it was passed a pointer. It will free the memory
that was allocated by the malloc/calloc/realloc call, regardless of what
that pointer may have been cast to.

Note that
Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));

is equivalent to
Aobj *ptrTob = calloc(1,sizeof (struct B));
Aobj *ptrToA = (struct A*) ptrTob;
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project


Jan 8 '07 #6
"David T. Ashley" <dt*@e3ft.comwr ites:
<la*******@gmai l.comwrote in message
news:11******** **************@ 38g2000cwa.goog legroups.com...
>>I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));

free(ptrToA) ;
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)?

malloc(), calloc(), and free() are block-oriented only. They operate only
in terms of a starting address and a length. There is no type information
involved.
Can someone explain again why people keep saying (in this NG) that ints or pointers
to chars etc might be stored in different memory blocks? And if they
are, how would one possibly use malloc?
Jan 9 '07 #7
Richard wrote:
"David T. Ashley" <dt*@e3ft.comwr ites:
<la*******@gmai l.comwrote in message
news:11******** **************@ 38g2000cwa.goog legroups.com...
>I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));

free(ptrToA);
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)?
malloc(), calloc(), and free() are block-oriented only. They operate only
in terms of a starting address and a length. There is no type information
involved.

Can someone explain again why people keep saying (in this NG) that ints or pointers
to chars etc might be stored in different memory blocks? And if they
are, how would one possibly use malloc?
I don't know what "stored in different memory blocks"
means or whether it has been said in some thread but
noone has said it in this thread.

Jan 9 '07 #8
"Spiros Bousbouras" <sp****@gmail.c omwrites:
Keith Thompson wrote:
>Incidentally , the standard doesn't *quite* guarantee that the initial
fields of your struct A and struct B will be laid out consistently,
unless you happen to declare a union of the two types, though it's
difficult to imagine an implementation in which they wouldn't match.
You might consider making the first member of struct B be of type
struct A, rather than duplicating all the fields explicitly; this
would also avoid any errors that might be introduced by writing the
same sequence of member declarations twice,

Since what is returned by calloc() is guaranteed to
be properly alligned for any type I don't see what
might go wrong even in theory. Unless you're saying
that sizeof(struct A) may be larger than sizeof(struct B).
Yes, sizeof(struct A) may theoretically, given a sufficiently insane
implementation, be larger than sizeof(struct B), but that's not what I
had in mind.

The code in question was:
| {
| struct A {<A fields>};
| struct B {<A fields+ <Bfields>};
|
| typedef struct A Aobj;
| typedef struct B Bobj;
|
| Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));
|
| free(ptrToA);
| }

I assumed that the reason for declaring struct B that way was to allow
the initial part of a struct B object to be treated as a struct A.
That's the only reason I can think of to allocate sizeof(struct B)
bytes.

There's one other thing I should mention here. calloc() initializes
the allocated memory to all-bits-zero. If struct A or struct B
contains members of some pointer or floating-point type, there's no
guarantee that this will set them to null pointers or 0.0,
respectively. It may be safer to use malloc() and then initialize the
members explicitly.

For example (ignoring the struct A vs. struct B business):

struct foo { /* ... */ };
const struct foo foo_zero = { 0 };
struct foo *ptr_to_foo = malloc(sizeof *ptr_to_foo);
if (ptr_to_foo == NULL) { /* OOPS! */ }
*ptr_to_foo = foo_zero;

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 9 '07 #9
Richard <rg****@gmail.c omwrites:
"David T. Ashley" <dt*@e3ft.comwr ites:
><la*******@gma il.comwrote in message
news:11******* *************** @38g2000cwa.goo glegroups.com.. .
>>>I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof (struct B));

free(ptrToA );
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)?

malloc(), calloc(), and free() are block-oriented only. They operate only
in terms of a starting address and a length. There is no type information
involved.

Can someone explain again why people keep saying (in this NG) that
ints or pointers to chars etc might be stored in different memory
blocks? And if they are, how would one possibly use malloc?
I don't think anyone has said so in this thread, particularly in the
article to which you replied. I think David was referring to the
"block" of memory allocated by each call to calloc or malloc.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 9 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
1628
by: Aaron Walker | last post by:
I apologize if this is a stupid question. I was just curious... is there any reason why free() doesn't set the pointer (that was passed to it) to NULL after giving the memory back to the heap? I decided to write a wrapper for free() to do just that, and I wondered why free() itself didn't do it. Aaron -- /usr/bin/fortune says: How can you work when the system's so crowded?
9
2404
by: zerro | last post by:
Hello, I try to understand heap overflows (under Linux), but can not understand one thing with freeing memory allocated with malloc(). Here it comes: I have a program called 1.c: main() { char *a, *b, *c, *d, *e; a = malloc(8);
36
2282
by: Martin Andert | last post by:
Hello, I have a question regarding malloc and free. Here my code sample: int main() { /* allocating dynamic memory for array */ int* array = (int*) malloc(5 * sizeof(int)); /* ... program code ... */
17
2150
by: kj | last post by:
How can one test if a pointer has been "freed" (i.e. with free())? My naive assumption was that such a pointer would equal NULL, but not so. Thanks, kj -- NOTE: In my address everything before the first period is backwards;
86
4157
by: Walter Roberson | last post by:
If realloc() finds it necessary to move the memory block, then does it free() the previously allocated block? The C89 standard has some reference to undefined behaviour if one realloc()'s memory that was freed by realloc(), but the only way explicitly mentioned in the C89 standard to free memory via realloc() is to realloc() it down to 0 bytes. I had always assumed it would automatically free the previous memory, but is the behaviour...
76
3702
by: dbansal | last post by:
Hi group, I have a question to ask you all. I have allocated some chunk of memory using ptr=(int*)malloc(). now I am trying to free that memory using free((void*)ptr). My question is does free() make ptr NULL? If not how do we know whether ptr memory has been freed already and we should not try to free the same memory twice. Man pages does not tell anything about this behavoiur. Thanks,
13
5024
by: Berk Birand | last post by:
Hi, I am working on a school project where we use lex/yacc to write a compiler for a fictional (Java-like) language. I have handled all the details about the yacc and lex files, but I still have a question regarding the dynamic memory allocation for strings. When the lex file encounters a variable name, I want it to pass this to yacc through yylval, and then retrieve it to add to a syntax tree. For this purpose, I wrote the following...
13
5083
by: Chad | last post by:
Excercise 6-5 Write a functon undef that will remove a name and defintion from the table maintained by lookup and install. Code: unsigned hash(char *s); void undef(char *s)
2
1915
by: Workarounder | last post by:
Hi! I have a program and in this program I have to do a lot of close´s and free´s. The program is something like this: static int finalize(FILE* f1, FILE* f2, char* c) { if (f1 != NULL) { fclose(f1); } if (f2 != NULL) {
0
10136
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9925
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9811
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7358
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6640
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5266
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5405
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3913
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2788
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.