473,386 Members | 1,830 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

freeing memory....partially

Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(sizeof(struct1)+sizeof(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 3021
On Sat, 04 Oct 2003 16:12:01 GMT, "f.**********@tiscalinet.it"
<f.**********@tiscalinet.it> wrote:
Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(sizeof(struct1)+sizeof(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.ru> 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.**********@tiscalinet.it> wrote in message
news:pa****************************@tiscalinet.it. ..
Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(sizeof(struct1)+sizeof(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.**********@tiscalinet.it"
<f.**********@tiscalinet.it> wrote:
Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(sizeof(struct1)+sizeof(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(struct2) 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.**********@tiscalinet.it" <f.**********@tiscalinet.it> writes:
Hi,
i would like to allocate two structures making only one malloc call.
So i do prt=malloc(sizeof(struct1)+sizeof(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(sizeof(struct1)+sizeof(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***********************@news.xs4all.nl>
Martijn <su*********************@hotNOFILTERmail.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
On Sun, 5 Oct 2003 16:40:11 +0200, "Martijn"
<su*********************@hotNOFILTERmail.com> wrote:
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 assume you meant fn_ptr.

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).


path is OK because sizeof(char) is always 1 so the computed address is
"properly aligned." and points exactly 1 byte beyond the struct. You
could achieve the same with
fn_ptr->path = (char*)(fn_ptr+1);

name is properly aligned for the same reason (but obviously points
somewhere inside the string pointed to by path).
<<Remove the del for email>>
Nov 13 '05 #11

<f.**********@tiscalinet.it> wrote in message
news:pa****************************@tiscalinet.it. ..
Thank you all very very much :-)))
Some answers:
To shott
If all you wanted to do was consolidate the allocations, a cleaner way wouldbe:

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 thecompiler 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?

There's not much to explain. Your original question was "does the ANSI
mandated malloc/free functions allow me to partially free memory". The
answer is, of course, no [1]. Hence, this suggestion, which is to use
another memory allocator which does provide the additional functionality
(whether you find an existing library or write it yourself). Since you
really don't specify exactly what functionality you do need, I can't provide
much more of a suggestion.
[1] Apart from realloc. I know you know this, and that realloc will not
meet your needs. I need to put in this caveat so that my answer is, in
fact, technically correct.

--
poncho

Nov 13 '05 #12
There's not much to explain. Your original question was "does the ANSI
mandated malloc/free functions allow me to partially free memory". The
answer is, of course, no [1]. Hence, this suggestion, which is to use
another memory allocator which does provide the additional functionality
(whether you find an existing library or write it yourself). Since you
really don't specify exactly what functionality you do need, I can't provide
much more of a suggestion.


Any axample of such a library capable of freeing a
part of the memory allocated?

francesco

Nov 13 '05 #13

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

Similar topics

5
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...
11
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...
6
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...
4
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...
5
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...
11
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....
66
by: karthikbalaguru | last post by:
Hi, Will 'free' return the memory Immediately to the OS ? Thx in advans, Karthik Balaguru
11
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...
25
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
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
0
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...

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.