Simple memory pool using no extra memorySuper simple templated memory pool in C++Memory Pool and Block...
There is only s̶i̶x̶t̶y one place he can be
How do I define a right arrow with bar in LaTeX?
Is HostGator storing my password in plaintext?
voltage of sounds of mp3files
Is there a problem with hiding "forgot password" until it's needed?
Is it okay / does it make sense for another player to join a running game of Munchkin?
What is the oldest known work of fiction?
How can I use the arrow sign in my bash prompt?
Mapping a list into a phase plot
when is out of tune ok?
Everything Bob says is false. How does he get people to trust him?
How will losing mobility of one hand affect my career as a programmer?
Go Pregnant or Go Home
Is there an Impartial Brexit Deal comparison site?
Increase performance creating Mandelbrot set in python
Coordinate position not precise
Can I use my Chinese passport to enter China after I acquired another citizenship?
At which point does a character regain all their Hit Dice?
What would happen if the UK refused to take part in EU Parliamentary elections?
Using parameter substitution on a Bash array
What defines a dissertation?
Bash method for viewing beginning and end of file
Can I Retrieve Email Addresses from BCC?
Short story about space worker geeks who zone out by 'listening' to radiation from stars
Simple memory pool using no extra memory
Super simple templated memory pool in C++Memory Pool and Block AlignmentCritique of realloc() wrapperSmart pointer memory poolDoes this simple memory pool use too much memory?Traversable memory poolFixed-Size Memory PoolBasic memory pool, alignment, thread safetyC++ object pool using C memory pool as baseFixed-sized memory pool in C
$begingroup$
I've borrowed the idea from the internet and I would like to know if my implementation is all right and what could be improved.
It uses the free memory to store links to each node, so there's no extra memory being used.
memory_pool.h
#ifndef MEMORY_POOL_H
#define MEMORY_POOL_H
#include <stdlib.h>
#define MEMORY_POOL_SUCCESS 1
#define MEMORY_POOL_ERROR 0
#define MEMORY_POOL_MINIMUM_SIZE sizeof(void *)
typedef struct {
void **head;
void *memory;
} Memory_Pool;
//size must be greater than or equal to MEMORY_POOL_MINIMUM_SIZE
int mp_init(Memory_Pool *mp, size_t size, size_t slots);
void mp_destroy(Memory_Pool *mp);
void *mp_get(Memory_Pool *mp);
void mp_release(Memory_Pool *mp, void *mem);
#endif
memory_pool.c
#include "memory_pool.h"
int mp_init(Memory_Pool *mp, size_t size, size_t slots)
{
//allocate memory
if((mp->memory = malloc(size * slots)) == NULL)
return MEMORY_POOL_ERROR;
//initialize
mp->head = NULL;
//add every slot to the list
char *end = (char *)mp->memory + size * slots;
for(char *ite = mp->memory; ite < end; ite += size)
mp_release(mp, ite);
return MEMORY_POOL_SUCCESS;
}
void mp_destroy(Memory_Pool *mp)
{
free(mp->memory);
}
void *mp_get(Memory_Pool *mp)
{
if(mp->head == NULL)
return NULL;
//store first address
void *temp = mp->head;
//link one past it
mp->head = *mp->head;
//return the first address
return temp;
}
void mp_release(Memory_Pool *mp, void *mem)
{
//store first address
void *temp = mp->head;
//link new node
mp->head = mem;
//link to the list from new node
*mp->head = temp;
}
c memory-management
$endgroup$
add a comment |
$begingroup$
I've borrowed the idea from the internet and I would like to know if my implementation is all right and what could be improved.
It uses the free memory to store links to each node, so there's no extra memory being used.
memory_pool.h
#ifndef MEMORY_POOL_H
#define MEMORY_POOL_H
#include <stdlib.h>
#define MEMORY_POOL_SUCCESS 1
#define MEMORY_POOL_ERROR 0
#define MEMORY_POOL_MINIMUM_SIZE sizeof(void *)
typedef struct {
void **head;
void *memory;
} Memory_Pool;
//size must be greater than or equal to MEMORY_POOL_MINIMUM_SIZE
int mp_init(Memory_Pool *mp, size_t size, size_t slots);
void mp_destroy(Memory_Pool *mp);
void *mp_get(Memory_Pool *mp);
void mp_release(Memory_Pool *mp, void *mem);
#endif
memory_pool.c
#include "memory_pool.h"
int mp_init(Memory_Pool *mp, size_t size, size_t slots)
{
//allocate memory
if((mp->memory = malloc(size * slots)) == NULL)
return MEMORY_POOL_ERROR;
//initialize
mp->head = NULL;
//add every slot to the list
char *end = (char *)mp->memory + size * slots;
for(char *ite = mp->memory; ite < end; ite += size)
mp_release(mp, ite);
return MEMORY_POOL_SUCCESS;
}
void mp_destroy(Memory_Pool *mp)
{
free(mp->memory);
}
void *mp_get(Memory_Pool *mp)
{
if(mp->head == NULL)
return NULL;
//store first address
void *temp = mp->head;
//link one past it
mp->head = *mp->head;
//return the first address
return temp;
}
void mp_release(Memory_Pool *mp, void *mem)
{
//store first address
void *temp = mp->head;
//link new node
mp->head = mem;
//link to the list from new node
*mp->head = temp;
}
c memory-management
$endgroup$
add a comment |
$begingroup$
I've borrowed the idea from the internet and I would like to know if my implementation is all right and what could be improved.
It uses the free memory to store links to each node, so there's no extra memory being used.
memory_pool.h
#ifndef MEMORY_POOL_H
#define MEMORY_POOL_H
#include <stdlib.h>
#define MEMORY_POOL_SUCCESS 1
#define MEMORY_POOL_ERROR 0
#define MEMORY_POOL_MINIMUM_SIZE sizeof(void *)
typedef struct {
void **head;
void *memory;
} Memory_Pool;
//size must be greater than or equal to MEMORY_POOL_MINIMUM_SIZE
int mp_init(Memory_Pool *mp, size_t size, size_t slots);
void mp_destroy(Memory_Pool *mp);
void *mp_get(Memory_Pool *mp);
void mp_release(Memory_Pool *mp, void *mem);
#endif
memory_pool.c
#include "memory_pool.h"
int mp_init(Memory_Pool *mp, size_t size, size_t slots)
{
//allocate memory
if((mp->memory = malloc(size * slots)) == NULL)
return MEMORY_POOL_ERROR;
//initialize
mp->head = NULL;
//add every slot to the list
char *end = (char *)mp->memory + size * slots;
for(char *ite = mp->memory; ite < end; ite += size)
mp_release(mp, ite);
return MEMORY_POOL_SUCCESS;
}
void mp_destroy(Memory_Pool *mp)
{
free(mp->memory);
}
void *mp_get(Memory_Pool *mp)
{
if(mp->head == NULL)
return NULL;
//store first address
void *temp = mp->head;
//link one past it
mp->head = *mp->head;
//return the first address
return temp;
}
void mp_release(Memory_Pool *mp, void *mem)
{
//store first address
void *temp = mp->head;
//link new node
mp->head = mem;
//link to the list from new node
*mp->head = temp;
}
c memory-management
$endgroup$
I've borrowed the idea from the internet and I would like to know if my implementation is all right and what could be improved.
It uses the free memory to store links to each node, so there's no extra memory being used.
memory_pool.h
#ifndef MEMORY_POOL_H
#define MEMORY_POOL_H
#include <stdlib.h>
#define MEMORY_POOL_SUCCESS 1
#define MEMORY_POOL_ERROR 0
#define MEMORY_POOL_MINIMUM_SIZE sizeof(void *)
typedef struct {
void **head;
void *memory;
} Memory_Pool;
//size must be greater than or equal to MEMORY_POOL_MINIMUM_SIZE
int mp_init(Memory_Pool *mp, size_t size, size_t slots);
void mp_destroy(Memory_Pool *mp);
void *mp_get(Memory_Pool *mp);
void mp_release(Memory_Pool *mp, void *mem);
#endif
memory_pool.c
#include "memory_pool.h"
int mp_init(Memory_Pool *mp, size_t size, size_t slots)
{
//allocate memory
if((mp->memory = malloc(size * slots)) == NULL)
return MEMORY_POOL_ERROR;
//initialize
mp->head = NULL;
//add every slot to the list
char *end = (char *)mp->memory + size * slots;
for(char *ite = mp->memory; ite < end; ite += size)
mp_release(mp, ite);
return MEMORY_POOL_SUCCESS;
}
void mp_destroy(Memory_Pool *mp)
{
free(mp->memory);
}
void *mp_get(Memory_Pool *mp)
{
if(mp->head == NULL)
return NULL;
//store first address
void *temp = mp->head;
//link one past it
mp->head = *mp->head;
//return the first address
return temp;
}
void mp_release(Memory_Pool *mp, void *mem)
{
//store first address
void *temp = mp->head;
//link new node
mp->head = mem;
//link to the list from new node
*mp->head = temp;
}
c memory-management
c memory-management
asked May 4 '14 at 11:06
2013Asker2013Asker
1,06921223
1,06921223
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
I see a few things that might be changed.
mp_init
First, consider checking the passed *mp
variable to see if it's NULL
at least within the mp_init
call. Alternatively, you could also allocate that structure within the mp_init
routine and return a pointer to it or NULL
on error.
The initialization is more complex than it needs to be. Rather than make repeated calls to mp_release
and do all of that pointer manipulation, you could use this:
char *ptr;
for (ptr = mp->memory; --slots; ptr+=size)
*(void **)ptr = ptr+size;
*(void **)ptr = NULL;
mp->head = mp->memory;
mp_release
Within mp_release
, there is no error checking. This might be OK if we're looking for extreme performance, but it might be nice to have at least a debug version that checks that mem
actually points to a slot. For that to work, of course, you'll have to add at least one more variable to the structure to contain the size
parameter.
mp_destroy
In mp_destroy
it might be prudent to set mp->head = NULL
so that any subsequent mp_get
attempts will fail.
$endgroup$
$begingroup$
Wouldn't settingmp->head = NULL
potentially hide a programmer's error?
$endgroup$
– 2013Asker
May 4 '14 at 13:28
1
$begingroup$
@2013Asker: Rather than hiding the error, it seems to me that the proposed change would make such an error easier to find and it costs nearly nothing.
$endgroup$
– Edward
May 4 '14 at 13:40
add a comment |
$begingroup$
The only addition I would make is:
int mp_init(Memory_Pool *mp, size_t size, size_t slots)
{
if (size < MEMORY_POOL_MINIMUM_SIZE)
{ return MEMORY_POOL_ERROR;
}
But note: There is extra memoey being used.
typedef struct {
void **head;
void *memory;
} Memory_Pool;
You need space to store the above structure.
How it is implemented:
A call to mp_init()
allocated a chunk of memory. This chunk of memory is slots
count number of items each of size size
.
// Lets examine this specific call:
Memory_Pool memory;
if (mp_init(&memory, sizeof(void*) * 4, 5) != MEMORY_POOL_SUCCESS)
{
exit(1);
}
if((mp->memory = malloc(size * slots)) == NULL)
return MEMORY_POOL_ERROR;
mp->head----->Random
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
mp->head = NULL;
mp->head-----|
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end = (char *)mp->memory + size * slots;
mp->head-----|
mp->memory----------->***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
for(char *ite = mp->memory; ite < end; ite += size)
mp_release(mp, ite);
// Iteration 1:
mp->head----------------|
/
mp->memory----------->**( null )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 2:
mp->memory----------->**( null )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 3:
mp->memory----------->**( null )*
* / *
* | *
* *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 4:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 5:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
char *end----------------->
return MEMORY_POOL_SUCCESS;
}
$endgroup$
$begingroup$
can you explain how the node linking works? The OP was last seen 4 years ago. Why is the head **void and not just *void? Why in the release function, void* mem is being assigned to void** head. I can't seem to understand the underlying logic, thanks.
$endgroup$
– susdu
7 hours ago
$begingroup$
@susdu Hope the diagram helps.
$endgroup$
– Martin York
11 mins ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f48919%2fsimple-memory-pool-using-no-extra-memory%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
I see a few things that might be changed.
mp_init
First, consider checking the passed *mp
variable to see if it's NULL
at least within the mp_init
call. Alternatively, you could also allocate that structure within the mp_init
routine and return a pointer to it or NULL
on error.
The initialization is more complex than it needs to be. Rather than make repeated calls to mp_release
and do all of that pointer manipulation, you could use this:
char *ptr;
for (ptr = mp->memory; --slots; ptr+=size)
*(void **)ptr = ptr+size;
*(void **)ptr = NULL;
mp->head = mp->memory;
mp_release
Within mp_release
, there is no error checking. This might be OK if we're looking for extreme performance, but it might be nice to have at least a debug version that checks that mem
actually points to a slot. For that to work, of course, you'll have to add at least one more variable to the structure to contain the size
parameter.
mp_destroy
In mp_destroy
it might be prudent to set mp->head = NULL
so that any subsequent mp_get
attempts will fail.
$endgroup$
$begingroup$
Wouldn't settingmp->head = NULL
potentially hide a programmer's error?
$endgroup$
– 2013Asker
May 4 '14 at 13:28
1
$begingroup$
@2013Asker: Rather than hiding the error, it seems to me that the proposed change would make such an error easier to find and it costs nearly nothing.
$endgroup$
– Edward
May 4 '14 at 13:40
add a comment |
$begingroup$
I see a few things that might be changed.
mp_init
First, consider checking the passed *mp
variable to see if it's NULL
at least within the mp_init
call. Alternatively, you could also allocate that structure within the mp_init
routine and return a pointer to it or NULL
on error.
The initialization is more complex than it needs to be. Rather than make repeated calls to mp_release
and do all of that pointer manipulation, you could use this:
char *ptr;
for (ptr = mp->memory; --slots; ptr+=size)
*(void **)ptr = ptr+size;
*(void **)ptr = NULL;
mp->head = mp->memory;
mp_release
Within mp_release
, there is no error checking. This might be OK if we're looking for extreme performance, but it might be nice to have at least a debug version that checks that mem
actually points to a slot. For that to work, of course, you'll have to add at least one more variable to the structure to contain the size
parameter.
mp_destroy
In mp_destroy
it might be prudent to set mp->head = NULL
so that any subsequent mp_get
attempts will fail.
$endgroup$
$begingroup$
Wouldn't settingmp->head = NULL
potentially hide a programmer's error?
$endgroup$
– 2013Asker
May 4 '14 at 13:28
1
$begingroup$
@2013Asker: Rather than hiding the error, it seems to me that the proposed change would make such an error easier to find and it costs nearly nothing.
$endgroup$
– Edward
May 4 '14 at 13:40
add a comment |
$begingroup$
I see a few things that might be changed.
mp_init
First, consider checking the passed *mp
variable to see if it's NULL
at least within the mp_init
call. Alternatively, you could also allocate that structure within the mp_init
routine and return a pointer to it or NULL
on error.
The initialization is more complex than it needs to be. Rather than make repeated calls to mp_release
and do all of that pointer manipulation, you could use this:
char *ptr;
for (ptr = mp->memory; --slots; ptr+=size)
*(void **)ptr = ptr+size;
*(void **)ptr = NULL;
mp->head = mp->memory;
mp_release
Within mp_release
, there is no error checking. This might be OK if we're looking for extreme performance, but it might be nice to have at least a debug version that checks that mem
actually points to a slot. For that to work, of course, you'll have to add at least one more variable to the structure to contain the size
parameter.
mp_destroy
In mp_destroy
it might be prudent to set mp->head = NULL
so that any subsequent mp_get
attempts will fail.
$endgroup$
I see a few things that might be changed.
mp_init
First, consider checking the passed *mp
variable to see if it's NULL
at least within the mp_init
call. Alternatively, you could also allocate that structure within the mp_init
routine and return a pointer to it or NULL
on error.
The initialization is more complex than it needs to be. Rather than make repeated calls to mp_release
and do all of that pointer manipulation, you could use this:
char *ptr;
for (ptr = mp->memory; --slots; ptr+=size)
*(void **)ptr = ptr+size;
*(void **)ptr = NULL;
mp->head = mp->memory;
mp_release
Within mp_release
, there is no error checking. This might be OK if we're looking for extreme performance, but it might be nice to have at least a debug version that checks that mem
actually points to a slot. For that to work, of course, you'll have to add at least one more variable to the structure to contain the size
parameter.
mp_destroy
In mp_destroy
it might be prudent to set mp->head = NULL
so that any subsequent mp_get
attempts will fail.
answered May 4 '14 at 12:38
EdwardEdward
47.5k378213
47.5k378213
$begingroup$
Wouldn't settingmp->head = NULL
potentially hide a programmer's error?
$endgroup$
– 2013Asker
May 4 '14 at 13:28
1
$begingroup$
@2013Asker: Rather than hiding the error, it seems to me that the proposed change would make such an error easier to find and it costs nearly nothing.
$endgroup$
– Edward
May 4 '14 at 13:40
add a comment |
$begingroup$
Wouldn't settingmp->head = NULL
potentially hide a programmer's error?
$endgroup$
– 2013Asker
May 4 '14 at 13:28
1
$begingroup$
@2013Asker: Rather than hiding the error, it seems to me that the proposed change would make such an error easier to find and it costs nearly nothing.
$endgroup$
– Edward
May 4 '14 at 13:40
$begingroup$
Wouldn't setting
mp->head = NULL
potentially hide a programmer's error?$endgroup$
– 2013Asker
May 4 '14 at 13:28
$begingroup$
Wouldn't setting
mp->head = NULL
potentially hide a programmer's error?$endgroup$
– 2013Asker
May 4 '14 at 13:28
1
1
$begingroup$
@2013Asker: Rather than hiding the error, it seems to me that the proposed change would make such an error easier to find and it costs nearly nothing.
$endgroup$
– Edward
May 4 '14 at 13:40
$begingroup$
@2013Asker: Rather than hiding the error, it seems to me that the proposed change would make such an error easier to find and it costs nearly nothing.
$endgroup$
– Edward
May 4 '14 at 13:40
add a comment |
$begingroup$
The only addition I would make is:
int mp_init(Memory_Pool *mp, size_t size, size_t slots)
{
if (size < MEMORY_POOL_MINIMUM_SIZE)
{ return MEMORY_POOL_ERROR;
}
But note: There is extra memoey being used.
typedef struct {
void **head;
void *memory;
} Memory_Pool;
You need space to store the above structure.
How it is implemented:
A call to mp_init()
allocated a chunk of memory. This chunk of memory is slots
count number of items each of size size
.
// Lets examine this specific call:
Memory_Pool memory;
if (mp_init(&memory, sizeof(void*) * 4, 5) != MEMORY_POOL_SUCCESS)
{
exit(1);
}
if((mp->memory = malloc(size * slots)) == NULL)
return MEMORY_POOL_ERROR;
mp->head----->Random
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
mp->head = NULL;
mp->head-----|
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end = (char *)mp->memory + size * slots;
mp->head-----|
mp->memory----------->***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
for(char *ite = mp->memory; ite < end; ite += size)
mp_release(mp, ite);
// Iteration 1:
mp->head----------------|
/
mp->memory----------->**( null )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 2:
mp->memory----------->**( null )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 3:
mp->memory----------->**( null )*
* / *
* | *
* *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 4:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 5:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
char *end----------------->
return MEMORY_POOL_SUCCESS;
}
$endgroup$
$begingroup$
can you explain how the node linking works? The OP was last seen 4 years ago. Why is the head **void and not just *void? Why in the release function, void* mem is being assigned to void** head. I can't seem to understand the underlying logic, thanks.
$endgroup$
– susdu
7 hours ago
$begingroup$
@susdu Hope the diagram helps.
$endgroup$
– Martin York
11 mins ago
add a comment |
$begingroup$
The only addition I would make is:
int mp_init(Memory_Pool *mp, size_t size, size_t slots)
{
if (size < MEMORY_POOL_MINIMUM_SIZE)
{ return MEMORY_POOL_ERROR;
}
But note: There is extra memoey being used.
typedef struct {
void **head;
void *memory;
} Memory_Pool;
You need space to store the above structure.
How it is implemented:
A call to mp_init()
allocated a chunk of memory. This chunk of memory is slots
count number of items each of size size
.
// Lets examine this specific call:
Memory_Pool memory;
if (mp_init(&memory, sizeof(void*) * 4, 5) != MEMORY_POOL_SUCCESS)
{
exit(1);
}
if((mp->memory = malloc(size * slots)) == NULL)
return MEMORY_POOL_ERROR;
mp->head----->Random
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
mp->head = NULL;
mp->head-----|
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end = (char *)mp->memory + size * slots;
mp->head-----|
mp->memory----------->***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
for(char *ite = mp->memory; ite < end; ite += size)
mp_release(mp, ite);
// Iteration 1:
mp->head----------------|
/
mp->memory----------->**( null )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 2:
mp->memory----------->**( null )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 3:
mp->memory----------->**( null )*
* / *
* | *
* *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 4:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 5:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
char *end----------------->
return MEMORY_POOL_SUCCESS;
}
$endgroup$
$begingroup$
can you explain how the node linking works? The OP was last seen 4 years ago. Why is the head **void and not just *void? Why in the release function, void* mem is being assigned to void** head. I can't seem to understand the underlying logic, thanks.
$endgroup$
– susdu
7 hours ago
$begingroup$
@susdu Hope the diagram helps.
$endgroup$
– Martin York
11 mins ago
add a comment |
$begingroup$
The only addition I would make is:
int mp_init(Memory_Pool *mp, size_t size, size_t slots)
{
if (size < MEMORY_POOL_MINIMUM_SIZE)
{ return MEMORY_POOL_ERROR;
}
But note: There is extra memoey being used.
typedef struct {
void **head;
void *memory;
} Memory_Pool;
You need space to store the above structure.
How it is implemented:
A call to mp_init()
allocated a chunk of memory. This chunk of memory is slots
count number of items each of size size
.
// Lets examine this specific call:
Memory_Pool memory;
if (mp_init(&memory, sizeof(void*) * 4, 5) != MEMORY_POOL_SUCCESS)
{
exit(1);
}
if((mp->memory = malloc(size * slots)) == NULL)
return MEMORY_POOL_ERROR;
mp->head----->Random
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
mp->head = NULL;
mp->head-----|
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end = (char *)mp->memory + size * slots;
mp->head-----|
mp->memory----------->***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
for(char *ite = mp->memory; ite < end; ite += size)
mp_release(mp, ite);
// Iteration 1:
mp->head----------------|
/
mp->memory----------->**( null )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 2:
mp->memory----------->**( null )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 3:
mp->memory----------->**( null )*
* / *
* | *
* *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 4:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 5:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
char *end----------------->
return MEMORY_POOL_SUCCESS;
}
$endgroup$
The only addition I would make is:
int mp_init(Memory_Pool *mp, size_t size, size_t slots)
{
if (size < MEMORY_POOL_MINIMUM_SIZE)
{ return MEMORY_POOL_ERROR;
}
But note: There is extra memoey being used.
typedef struct {
void **head;
void *memory;
} Memory_Pool;
You need space to store the above structure.
How it is implemented:
A call to mp_init()
allocated a chunk of memory. This chunk of memory is slots
count number of items each of size size
.
// Lets examine this specific call:
Memory_Pool memory;
if (mp_init(&memory, sizeof(void*) * 4, 5) != MEMORY_POOL_SUCCESS)
{
exit(1);
}
if((mp->memory = malloc(size * slots)) == NULL)
return MEMORY_POOL_ERROR;
mp->head----->Random
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
mp->head = NULL;
mp->head-----|
mp->memory---> ***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end = (char *)mp->memory + size * slots;
mp->head-----|
mp->memory----------->***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
for(char *ite = mp->memory; ite < end; ite += size)
mp_release(mp, ite);
// Iteration 1:
mp->head----------------|
/
mp->memory----------->**( null )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 2:
mp->memory----------->**( null )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 3:
mp->memory----------->**( null )*
* / *
* | *
* *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 4:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
* *
* *
* *
* *
***********
char *end----------------->
// Iteration 5:
mp->memory----------->**( null )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
* | *
* | *
**( * )*
* / *
* | *
mp->head--------------*-| | *
* / | *
**( * )*
char *end----------------->
return MEMORY_POOL_SUCCESS;
}
edited 11 mins ago
answered May 4 '14 at 11:38
Martin YorkMartin York
73.8k488271
73.8k488271
$begingroup$
can you explain how the node linking works? The OP was last seen 4 years ago. Why is the head **void and not just *void? Why in the release function, void* mem is being assigned to void** head. I can't seem to understand the underlying logic, thanks.
$endgroup$
– susdu
7 hours ago
$begingroup$
@susdu Hope the diagram helps.
$endgroup$
– Martin York
11 mins ago
add a comment |
$begingroup$
can you explain how the node linking works? The OP was last seen 4 years ago. Why is the head **void and not just *void? Why in the release function, void* mem is being assigned to void** head. I can't seem to understand the underlying logic, thanks.
$endgroup$
– susdu
7 hours ago
$begingroup$
@susdu Hope the diagram helps.
$endgroup$
– Martin York
11 mins ago
$begingroup$
can you explain how the node linking works? The OP was last seen 4 years ago. Why is the head **void and not just *void? Why in the release function, void* mem is being assigned to void** head. I can't seem to understand the underlying logic, thanks.
$endgroup$
– susdu
7 hours ago
$begingroup$
can you explain how the node linking works? The OP was last seen 4 years ago. Why is the head **void and not just *void? Why in the release function, void* mem is being assigned to void** head. I can't seem to understand the underlying logic, thanks.
$endgroup$
– susdu
7 hours ago
$begingroup$
@susdu Hope the diagram helps.
$endgroup$
– Martin York
11 mins ago
$begingroup$
@susdu Hope the diagram helps.
$endgroup$
– Martin York
11 mins ago
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f48919%2fsimple-memory-pool-using-no-extra-memory%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown