473,659 Members | 2,659 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

freeing memory....parti ally

Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(size of(struct1)+siz eof(struct2));
After this operation i make two pointers one to the first struct (ptr1=ptr),
the other to second struct(ptr2=ptr +sizeof(struct2 )).
These two pointer are later used by two threads in mutual exclusion so
thread1 can't access ptr2 and thread2 can't access ptr1.
At some time thread2 wants to free his part of memory but a
free(ptr2) or free((struct struct2 *)ptr) or something similar leads to
a SEGV. This happens, i think, because i must pass to free() a pointer
returned by a previous malloc call. But why this limitation?
Is it possible, in some way, to free only a part of the memory allocated
by malloc?
Remember that i cannot use realloc beacause thread2 cannot access ptr1.

Thank u very much
Francesco Oppedisano
Nov 13 '05 #1
12 3060
On Sat, 04 Oct 2003 16:12:01 GMT, "f.**********@t iscalinet.it"
<f.**********@t iscalinet.it> wrote:
Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(size of(struct1)+siz eof(struct2));
After this operation i make two pointers one to the first struct (ptr1=ptr),
the other to second struct(ptr2=ptr +sizeof(struct2 )).
If ptr is of type (struct1 *), then
struct2 *ptr2 = (void *) (ptr+1);
will suffice.
These two pointer are later used by two threads in mutual exclusion so
thread1 can't access ptr2 and thread2 can't access ptr1.
At some time thread2 wants to free his part of memory but a
free(ptr2) or free((struct struct2 *)ptr) or something similar leads to
a SEGV. This happens, i think, because i must pass to free() a pointer
returned by a previous malloc call. But why this limitation?
Easy: free() expects whatever malloc() returned, and nothing else (barring NULL,
ofcourse). It's undefined behaviour otherwise.
Is it possible, in some way, to free only a part of the memory allocated
by malloc?
Hmm, yes, do a realloc() to shrink the memory.
Remember that i cannot use realloc beacause thread2 cannot access ptr1.


Then all bets are off. Try redesigning your code!

Nov 13 '05 #2
On Sat, 04 Oct 2003 21:28:36 +0500, rihad <ri***@mail.r u> wrote:
Easy: free() expects whatever malloc() returned, and nothing else (barring NULL,
ofcourse).


The part in parentheses is superfluous. Let's optimize it away:

Easy: free() expects whatever malloc() returned, and nothing else.
Nov 13 '05 #3

<f.**********@t iscalinet.it> wrote in message
news:pa******** *************** *****@tiscaline t.it...
Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(size of(struct1)+siz eof(struct2));
After this operation i make two pointers one to the first struct (ptr1=ptr), the other to second struct(ptr2=ptr +sizeof(struct2 )). If ptr is of type (struct1*), and the structure alignments come out correct
(which you can't really find out in a platform independent way), the correct
way to do this is:
ptr2 = (struct2*)(ptr + 1);

If all you wanted to do was consolidate the allocations, a cleaner way would
be:

struct combined_struct {
struct1 s1;
struct2 s2;
};
struct combined_struct *p = malloc( sizeof *p );
/* Don't forget the malloc failure check */
ptr = &p->s1;
ptr2 = &p->s2;

This has the advantage that you don't have to worry about alignment, as the
compiler will take care of that for you.

However, this doesn't address the next requirement:
These two pointer are later used by two threads in mutual exclusion so
thread1 can't access ptr2 and thread2 can't access ptr1.
At some time thread2 wants to free his part of memory but a
free(ptr2) or free((struct struct2 *)ptr) or something similar leads to
a SEGV. This happens, i think, because i must pass to free() a pointer
returned by a previous malloc call. But why this limitation?
Is it possible, in some way, to free only a part of the memory allocated
by malloc?

No. it is not possible. Apart from realloc, the only way to free allocated
memory is to call free, which will free all the memory that malloc
allocated. To do what you want to do, you either need to:

- Malloc struct1 and struct2 separately, or
- Use a memory allocator that provides the additional functionality you
want.

BTW: why is allocating the two structures separately difficult?
--
poncho
Nov 13 '05 #4
On Sat, 04 Oct 2003 16:12:01 GMT, "f.**********@t iscalinet.it"
<f.**********@t iscalinet.it> wrote:
Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(size of(struct1)+siz eof(struct2));
After this operation i make two pointers one to the first struct (ptr1=ptr),
the other to second struct(ptr2=ptr +sizeof(struct2 )).
Several problems here. Assuming struct1 and struct2 are typedef names
for the appropriate structures and ptr1 and ptr2 are pointers to each
type:

You want ptr2 to point sizeof(struct1) bytes beyond ptr1, not
sizeof(struct2) bytes.

This is not the way pointer arithmetic works. Whenever you add a
quantity to a pointer, the compiler automatically factors in the size
of whatever the pointer points to. In this case, you would use
ptr2 = (struct2*)(ptr1 +1)
which would cause ptr2 to have the value described above.

Attempting to use ptr2 after this type of calculation may produce
undefined behavior if the value ptr1+1 is not properly aligned for a
struct2. Consider the simple case where int is aligned on a multiple
of 4 and double is aligned on a multiple of 8.
typedef struct{int i;} struct1;
typedef struct{double d;} struct2;
malloc is guaranteed to return a value in ptr that is a multiple of 8.
This value can be assigned to ptr1 and is a suitable address for
struct1. ptr2 will be assigned a value 4 bytes greater than the value
in ptr1 which is guaranteed to be improperly aligned for struct2.

To make this work, you have to allocate enough space for the
maximum of sizeof(struct1) plus n*sizeof(struct 2) plus
sizeof(struct2) , where n is sufficiently large enough to make the
second term at least as big as the first. When you compute ptr2, it
needs to be:
ptr2 = (struct2*)ptr1 + n;
You can compute n at run time if need be with
n = sizeof(struct2)/sizeof(struct1) + 1;
These two pointer are later used by two threads in mutual exclusion so
thread1 can't access ptr2 and thread2 can't access ptr1.
At some time thread2 wants to free his part of memory but a
free(ptr2) or free((struct struct2 *)ptr) or something similar leads to
a SEGV. This happens, i think, because i must pass to free() a pointer
returned by a previous malloc call. But why this limitation?
The answer to the why is because that is what the language standard
says. Furthermore, there is no parameter to free stating how much
memory is to be freed so free will always release the same amount that
was originally requested. There is no capability to free part of the
allocation.
Is it possible, in some way, to free only a part of the memory allocated
by malloc?
Nope.
Remember that i cannot use realloc beacause thread2 cannot access ptr1.


Why do you need both structures in the same malloc? By your
description, the are never processed together. Independent objects
should be really independent.

<<Remove the del for email>>
Nov 13 '05 #5
"f.**********@t iscalinet.it" <f.**********@t iscalinet.it> writes:
Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(size of(struct1)+siz eof(struct2));
After this operation i make two pointers one to the first struct (ptr1=ptr),
the other to second struct(ptr2=ptr +sizeof(struct2 )).
This will only work if you are unlucky. ptr2's location may not
be correctly aligned for accesses to struct2's members: undefined
behavior is the result.

One thing that should work is to ensure that the size fed to
malloc() is twice the maximum of (sizeof struct1) and (sizeof
struct2), and do ptr2 = ((struct struct2 *)(ptr)) + 1.

This will work because, at any point you can validly treat ptr as
pointing to an array of char, an array of struct1 or an array of
struct2 to satisfy the standard's constraints (I think... can
anyone think of a reason why a standard-conformant implementation
could validly fail to digest such a hideous monstrosity)?

But there's no good reason to do this, so don't. Especially since
you can't do what you discuss below.
These two pointer are later used by two threads in mutual exclusion so
thread1 can't access ptr2 and thread2 can't access ptr1.
At some time thread2 wants to free his part of memory but a
free(ptr2) or free((struct struct2 *)ptr) or something similar leads to
a SEGV. This happens, i think, because i must pass to free() a pointer
returned by a previous malloc call. But why this limitation?
Is it possible, in some way, to free only a part of the memory allocated
by malloc?
Remember that i cannot use realloc beacause thread2 cannot access ptr1.


There is not a way to do what you wish. You really shouldn't
restrict yourself to a single malloc() call; use two.

-Micah
Nov 13 '05 #6
Hi,
This will only work if you are unlucky. ptr2's location may not
be correctly aligned for accesses to struct2's members: undefined
behavior is the result.


On that same line: if one has a structure of strings (for example, info for
a file), like so:

struct filename
{
char *path;
char *name;
}

Is the following "valid" or undefined behaviour:

struct filename *fn_ptr;
char fullpath[MAX_PATH + 1];
int pathlength;

/* code to fetch the file path and */
/* determine the length of the path */

fn_ptr = malloc(sizeof(* fn_ptr)
+ strlen(fullpath ) + 1);
/* check for errors */

fn_ptr->path = (char*)fn_ptr + sizeof(*fn_ptr) ;
fn_ptr->name = fn_ptr->path + pathlength;

strcpy(fp_ptr->path, fullpath);

I have code very similar to this in one of my DLLs. It works, but is it
defined behaviour/portable? Or does it suffer from the same allignment
problem? (I would think it is portable, BTW).

--
Martijn
http://www.sereneconcepts.nl
Nov 13 '05 #7
> i would like to allocate two structures making only one malloc call.
So i do prt=malloc(size of(struct1)+siz eof(struct2));
After this operation i make two pointers one to the first struct
(ptr1=ptr), the other to second struct(ptr2=ptr +sizeof(struct2 )).
These two pointer are later used by two threads in mutual exclusion so
thread1 can't access ptr2 and thread2 can't access ptr1.
At some time thread2 wants to free his part of memory but a
free(ptr2) or free((struct struct2 *)ptr) or something similar leads
to
a SEGV. This happens, i think, because i must pass to free() a pointer
returned by a previous malloc call. But why this limitation?
Is it possible, in some way, to free only a part of the memory
allocated
by malloc?
Remember that i cannot use realloc beacause thread2 cannot access
ptr1.


The problem worsens if you want to only delete ptr1. How are you going to
tell free not to release _all_ of the memory it allocated the that pointer?

--
Martijn
http://www.sereneconcepts.nl
Nov 13 '05 #8
In article <3f************ ***********@new s.xs4all.nl>
Martijn <su************ *********@hotNO FILTERmail.com> writes:
[snippage]
/* code to fetch the file path and */
/* determine the length of the path */

fn_ptr = malloc(sizeof(* fn_ptr)
+ strlen(fullpath ) + 1);
/* check for errors */

fn_ptr->path = (char*)fn_ptr + sizeof(*fn_ptr) ;
fn_ptr->name = fn_ptr->path + pathlength;

strcpy(fp_ptr->path, fullpath);

I have code very similar to this in one of my DLLs. It works, but is it
defined behaviour/portable? Or does it suffer from the same allignment
problem? (I would think it is portable, BTW).


This code is OK, because "char *" is required to have the least
alignment constraints in C. Thus, no matter how big
"sizeof *fn_ptr" is, (char *)fn_ptr + sizeof *fn_ptr is
correctly aligned for more "char"s.

I would, however, write the assignment to fn_ptr->path as:

fn_ptr->path = (char *)(fn_ptr + 1);

which has exactly the same effect, but is more concise.
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://67.40.109.61/torek/index.html (for the moment)
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 13 '05 #9
Thank you all very very much :-)))
Some answers:
To shott
If all you wanted to do was consolidate the allocations, a cleaner way would
be: struct combined_struct {
struct1 s1;
struct2 s2;
};
struct combined_struct *p = malloc( sizeof *p );
/* Don't forget the malloc failure check */
ptr = &p->s1;
ptr2 = &p->s2; This has the advantage that you don't have to worry about alignment, as the
compiler will take care of that for you.


This is exactly the way the allocation is really made.
But te real problem was the free() function, so i didn't
explain that allocation in detail. Sorry :-)
Bisides i cannot understand your second suggestion:

- Use a memory allocator that provides the additional functionality you
want.

Can u explain this please?

To Micah and Barry
As i wrote some lines above i really do ptr2 = &p->s2; so...no problem
about pointer arithmetic.

Regards
Francesco Oppedisano

Nov 13 '05 #10

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

Similar topics

5
22971
by: disco | last post by:
I am working on this example from a book "C Primer Plus" by Prata 4th edition - p. 672. There is no erata on this problem at the publisher's website. 1) Is it a violation of copyright laws to post example code from a book to a newsgroup? 2) The program crashes as it tries to free memory and I would like to know the best way to correct THIS section of the code. By assigning current = head, current now points to the first structure in...
11
2284
by: Rodrigo Dominguez | last post by:
there are sometimes that I use third party libraries, I use some functions that returns char * or structs, etc. sometimes the memory that is returned by those libraries, when I try to free this memory whith the function free, it brokes my application, and sometimes it's ok, why? how do I realize when I have to free the memory that is allocated by third party libraries and why sometimes I don't have to free this memory? Thank you
6
2761
by: Fernando Cacciola | last post by:
Help me out here please: While watching Brad Abraham's MSDN TV talk about the Dispose pattern, refering to: public virtual void Dispose ( bool disposing ) { if ( disposing ) { <-- WHAT GOES HERE -->
4
36527
by: Atul Sureka | last post by:
Hi, I want to free the object memory in C# - like we do using 'delete' keyword in C++. Lets say I have an object of some class and I want to explicitly free the memory. C# do not have any free or delete keyword to do so. Also I don't want to wait for the GC to be called.
5
3159
by: Amogh | last post by:
Hi, My question is related to setting freed pointers to NULL. After freeing a pointer: 1) Should the freeing routine also be responsible for setting the pointer to null? 2) Or, should the client/user code be responsible for doing it? On what basis should a decision be made favouring either case ?
11
4950
by: harsh123 | last post by:
I wish to add a new datatype to help me in doing mathametical computations.We all know that the system has got limited amount of memory ie we cannot create an array of very big size. for example a. The new data type will partially use RAM and partially file.For example if i declare an array of size 100000000 Try to compile this program #include"stdio.h" int a = {1,2,3,4}; int main() { return 0;
66
3677
by: karthikbalaguru | last post by:
Hi, Will 'free' return the memory Immediately to the OS ? Thx in advans, Karthik Balaguru
11
1999
by: vivek | last post by:
Hello, I have a pointer to a main structure which again consists of structures, enums, char, int, float and again complex structures. When i free all the contents of the main structure, it takes me a lot of time (since i have to loop determining the data type and freeing it). Is there any idea to free all the contents of the structure in shortest possible time.
25
4711
by: Andreas Eibach | last post by:
Hi again, one of the other big woes I'm having... typedef struct perBlockStru /* (structure) Long words per block */ { unsigned long *lword; } lwperBlockStru_t;
0
8427
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8332
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8851
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...
0
8746
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8627
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
6179
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
5649
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
4335
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
1975
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.