Own free() in c | melt free data blocks












0















i had to write my own free & malloc function.
So far I have not had a problem with that, but now I am supposed to merge neighboring free memory blocks in the halde_free() function. I would be really grateful if you could help me there.



    #include "halde.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>

/// Magic value for occupied memory chunks.
#define MAGIC ((void*)0xbaadf00d)

/// Size of the heap (in bytes).
#define SIZE (1024*1024*1)

/// Memory-chunk structure.
struct mblock {
struct mblock *next;
size_t size;
char memory;
};

/// Heap-memory area.
char memory[SIZE];

/// Pointer to the first element of the free-memory list.
static struct mblock *head;

/// Helper function to visualise the current state of the free-memory list.
void halde_print(void) {
struct mblock* lauf = head;

// Empty list
if ( head == NULL ) {
fprintf(stderr, "(empty)n");
return;
}

// Print each element in the list
while ( lauf ) {
fprintf(stderr, "(addr: 0x%08zx, off: %7zu, ", (uintptr_t) lauf, (uintptr_t)lauf - (uintptr_t)memory);
fflush(stderr);
fprintf(stderr, "size: %7zu)", lauf->size);
fflush(stderr);

if ( lauf->next != NULL ) {
fprintf(stderr, " --> ");
fflush(stderr);
}
lauf = lauf->next;
}
fprintf(stderr, "n");
fflush(stderr);
}

void *halde_malloc (size_t size) {
static int initialized = 0;

if(initialized == 0){
head = (struct mblock *) memory;
head->size = sizeof(memory) - sizeof (struct mblock);
head->next = NULL;
initialized = 1;
}

if(size == 0){
return NULL;
}

struct mblock *lauf = head;
struct mblock **prev_next = &head;

while (lauf != NULL && lauf->size < size){
prev_next = &(lauf->next);
lauf = *prev_next;
}

if(lauf == NULL){
errno = ENOMEM;
return NULL;
}

if((lauf->size -size) <= sizeof(struct mblock)){
*prev_next = lauf->next;
} else {
//mblock anlegen und init.
struct mblock* neu = (struct mblock*) (lauf->memory + size);
neu->size = lauf->size - sizeof(struct mblock) - size;
neu->next = lauf->next;

//mblock anpassen
lauf->size = size;

//verketten wiederherstellen
*prev_next = neu;
}

lauf->next = MAGIC;

return lauf->memory;
}

void halde_free (void *ptr) {
if(ptr == NULL){
return;
}

struct mblock *mbp = (struct mblock *) ptr - 1;
if(mbp->next != MAGIC){
abort();
} else {
mbp->next = head;
head = mbp;
}
}


The code works so far but i have really no idea how to merge blocks..
The memory management runs over a simply linked lists. The variable head points to the first free memory block.



My idea is to merge the blocks directly in the else part but i don't have a good idea to do that..










share|improve this question























  • I don't get why you're comparing the next pointer to MAGIC and aborting if that's not what's there.

    – Thomas Jager
    Nov 21 '18 at 12:57











  • If you malloc a block the next element of this block is MAGIC. (lauf->next = MAGIC;) And in the free() you have to check if the element you want to free can be freed at all or if it is already free.

    – Nicooost
    Nov 21 '18 at 13:14











  • This is rather broad question. So you have a linked list, with list items representing memory blocks. And then you need to find the list items which point to adjacent memory blocks, and remove one, and fix start and length of the other to cover the memory area of both. Simple brute force way would be to traverse the free list, and test if the freed block can be merged with existing free block (either before or after), and then add it as last in the list if no suitable merge candidate was found.

    – hyde
    Nov 21 '18 at 15:25











  • After that works, you might want to check if the newly enlarged free block could now be merged too (in case the freed block filled a gap between two free blocks).

    – hyde
    Nov 21 '18 at 15:26













  • A more efficient solution would involve using some more advanced data structure (such as a tree of some kind) to hold the free blocks, so you wouldn't have to traverse the entire list to find possible merge candidates. Slight improvement could be achieved by keeping the free list sorted (which is basically free, since you need to traverse it anyway), so you can stop searching earlier.

    – hyde
    Nov 21 '18 at 15:29


















0















i had to write my own free & malloc function.
So far I have not had a problem with that, but now I am supposed to merge neighboring free memory blocks in the halde_free() function. I would be really grateful if you could help me there.



    #include "halde.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>

/// Magic value for occupied memory chunks.
#define MAGIC ((void*)0xbaadf00d)

/// Size of the heap (in bytes).
#define SIZE (1024*1024*1)

/// Memory-chunk structure.
struct mblock {
struct mblock *next;
size_t size;
char memory;
};

/// Heap-memory area.
char memory[SIZE];

/// Pointer to the first element of the free-memory list.
static struct mblock *head;

/// Helper function to visualise the current state of the free-memory list.
void halde_print(void) {
struct mblock* lauf = head;

// Empty list
if ( head == NULL ) {
fprintf(stderr, "(empty)n");
return;
}

// Print each element in the list
while ( lauf ) {
fprintf(stderr, "(addr: 0x%08zx, off: %7zu, ", (uintptr_t) lauf, (uintptr_t)lauf - (uintptr_t)memory);
fflush(stderr);
fprintf(stderr, "size: %7zu)", lauf->size);
fflush(stderr);

if ( lauf->next != NULL ) {
fprintf(stderr, " --> ");
fflush(stderr);
}
lauf = lauf->next;
}
fprintf(stderr, "n");
fflush(stderr);
}

void *halde_malloc (size_t size) {
static int initialized = 0;

if(initialized == 0){
head = (struct mblock *) memory;
head->size = sizeof(memory) - sizeof (struct mblock);
head->next = NULL;
initialized = 1;
}

if(size == 0){
return NULL;
}

struct mblock *lauf = head;
struct mblock **prev_next = &head;

while (lauf != NULL && lauf->size < size){
prev_next = &(lauf->next);
lauf = *prev_next;
}

if(lauf == NULL){
errno = ENOMEM;
return NULL;
}

if((lauf->size -size) <= sizeof(struct mblock)){
*prev_next = lauf->next;
} else {
//mblock anlegen und init.
struct mblock* neu = (struct mblock*) (lauf->memory + size);
neu->size = lauf->size - sizeof(struct mblock) - size;
neu->next = lauf->next;

//mblock anpassen
lauf->size = size;

//verketten wiederherstellen
*prev_next = neu;
}

lauf->next = MAGIC;

return lauf->memory;
}

void halde_free (void *ptr) {
if(ptr == NULL){
return;
}

struct mblock *mbp = (struct mblock *) ptr - 1;
if(mbp->next != MAGIC){
abort();
} else {
mbp->next = head;
head = mbp;
}
}


The code works so far but i have really no idea how to merge blocks..
The memory management runs over a simply linked lists. The variable head points to the first free memory block.



My idea is to merge the blocks directly in the else part but i don't have a good idea to do that..










share|improve this question























  • I don't get why you're comparing the next pointer to MAGIC and aborting if that's not what's there.

    – Thomas Jager
    Nov 21 '18 at 12:57











  • If you malloc a block the next element of this block is MAGIC. (lauf->next = MAGIC;) And in the free() you have to check if the element you want to free can be freed at all or if it is already free.

    – Nicooost
    Nov 21 '18 at 13:14











  • This is rather broad question. So you have a linked list, with list items representing memory blocks. And then you need to find the list items which point to adjacent memory blocks, and remove one, and fix start and length of the other to cover the memory area of both. Simple brute force way would be to traverse the free list, and test if the freed block can be merged with existing free block (either before or after), and then add it as last in the list if no suitable merge candidate was found.

    – hyde
    Nov 21 '18 at 15:25











  • After that works, you might want to check if the newly enlarged free block could now be merged too (in case the freed block filled a gap between two free blocks).

    – hyde
    Nov 21 '18 at 15:26













  • A more efficient solution would involve using some more advanced data structure (such as a tree of some kind) to hold the free blocks, so you wouldn't have to traverse the entire list to find possible merge candidates. Slight improvement could be achieved by keeping the free list sorted (which is basically free, since you need to traverse it anyway), so you can stop searching earlier.

    – hyde
    Nov 21 '18 at 15:29
















0












0








0








i had to write my own free & malloc function.
So far I have not had a problem with that, but now I am supposed to merge neighboring free memory blocks in the halde_free() function. I would be really grateful if you could help me there.



    #include "halde.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>

/// Magic value for occupied memory chunks.
#define MAGIC ((void*)0xbaadf00d)

/// Size of the heap (in bytes).
#define SIZE (1024*1024*1)

/// Memory-chunk structure.
struct mblock {
struct mblock *next;
size_t size;
char memory;
};

/// Heap-memory area.
char memory[SIZE];

/// Pointer to the first element of the free-memory list.
static struct mblock *head;

/// Helper function to visualise the current state of the free-memory list.
void halde_print(void) {
struct mblock* lauf = head;

// Empty list
if ( head == NULL ) {
fprintf(stderr, "(empty)n");
return;
}

// Print each element in the list
while ( lauf ) {
fprintf(stderr, "(addr: 0x%08zx, off: %7zu, ", (uintptr_t) lauf, (uintptr_t)lauf - (uintptr_t)memory);
fflush(stderr);
fprintf(stderr, "size: %7zu)", lauf->size);
fflush(stderr);

if ( lauf->next != NULL ) {
fprintf(stderr, " --> ");
fflush(stderr);
}
lauf = lauf->next;
}
fprintf(stderr, "n");
fflush(stderr);
}

void *halde_malloc (size_t size) {
static int initialized = 0;

if(initialized == 0){
head = (struct mblock *) memory;
head->size = sizeof(memory) - sizeof (struct mblock);
head->next = NULL;
initialized = 1;
}

if(size == 0){
return NULL;
}

struct mblock *lauf = head;
struct mblock **prev_next = &head;

while (lauf != NULL && lauf->size < size){
prev_next = &(lauf->next);
lauf = *prev_next;
}

if(lauf == NULL){
errno = ENOMEM;
return NULL;
}

if((lauf->size -size) <= sizeof(struct mblock)){
*prev_next = lauf->next;
} else {
//mblock anlegen und init.
struct mblock* neu = (struct mblock*) (lauf->memory + size);
neu->size = lauf->size - sizeof(struct mblock) - size;
neu->next = lauf->next;

//mblock anpassen
lauf->size = size;

//verketten wiederherstellen
*prev_next = neu;
}

lauf->next = MAGIC;

return lauf->memory;
}

void halde_free (void *ptr) {
if(ptr == NULL){
return;
}

struct mblock *mbp = (struct mblock *) ptr - 1;
if(mbp->next != MAGIC){
abort();
} else {
mbp->next = head;
head = mbp;
}
}


The code works so far but i have really no idea how to merge blocks..
The memory management runs over a simply linked lists. The variable head points to the first free memory block.



My idea is to merge the blocks directly in the else part but i don't have a good idea to do that..










share|improve this question














i had to write my own free & malloc function.
So far I have not had a problem with that, but now I am supposed to merge neighboring free memory blocks in the halde_free() function. I would be really grateful if you could help me there.



    #include "halde.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>

/// Magic value for occupied memory chunks.
#define MAGIC ((void*)0xbaadf00d)

/// Size of the heap (in bytes).
#define SIZE (1024*1024*1)

/// Memory-chunk structure.
struct mblock {
struct mblock *next;
size_t size;
char memory;
};

/// Heap-memory area.
char memory[SIZE];

/// Pointer to the first element of the free-memory list.
static struct mblock *head;

/// Helper function to visualise the current state of the free-memory list.
void halde_print(void) {
struct mblock* lauf = head;

// Empty list
if ( head == NULL ) {
fprintf(stderr, "(empty)n");
return;
}

// Print each element in the list
while ( lauf ) {
fprintf(stderr, "(addr: 0x%08zx, off: %7zu, ", (uintptr_t) lauf, (uintptr_t)lauf - (uintptr_t)memory);
fflush(stderr);
fprintf(stderr, "size: %7zu)", lauf->size);
fflush(stderr);

if ( lauf->next != NULL ) {
fprintf(stderr, " --> ");
fflush(stderr);
}
lauf = lauf->next;
}
fprintf(stderr, "n");
fflush(stderr);
}

void *halde_malloc (size_t size) {
static int initialized = 0;

if(initialized == 0){
head = (struct mblock *) memory;
head->size = sizeof(memory) - sizeof (struct mblock);
head->next = NULL;
initialized = 1;
}

if(size == 0){
return NULL;
}

struct mblock *lauf = head;
struct mblock **prev_next = &head;

while (lauf != NULL && lauf->size < size){
prev_next = &(lauf->next);
lauf = *prev_next;
}

if(lauf == NULL){
errno = ENOMEM;
return NULL;
}

if((lauf->size -size) <= sizeof(struct mblock)){
*prev_next = lauf->next;
} else {
//mblock anlegen und init.
struct mblock* neu = (struct mblock*) (lauf->memory + size);
neu->size = lauf->size - sizeof(struct mblock) - size;
neu->next = lauf->next;

//mblock anpassen
lauf->size = size;

//verketten wiederherstellen
*prev_next = neu;
}

lauf->next = MAGIC;

return lauf->memory;
}

void halde_free (void *ptr) {
if(ptr == NULL){
return;
}

struct mblock *mbp = (struct mblock *) ptr - 1;
if(mbp->next != MAGIC){
abort();
} else {
mbp->next = head;
head = mbp;
}
}


The code works so far but i have really no idea how to merge blocks..
The memory management runs over a simply linked lists. The variable head points to the first free memory block.



My idea is to merge the blocks directly in the else part but i don't have a good idea to do that..







c memory-management merge malloc free






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 '18 at 12:53









NicooostNicooost

71




71













  • I don't get why you're comparing the next pointer to MAGIC and aborting if that's not what's there.

    – Thomas Jager
    Nov 21 '18 at 12:57











  • If you malloc a block the next element of this block is MAGIC. (lauf->next = MAGIC;) And in the free() you have to check if the element you want to free can be freed at all or if it is already free.

    – Nicooost
    Nov 21 '18 at 13:14











  • This is rather broad question. So you have a linked list, with list items representing memory blocks. And then you need to find the list items which point to adjacent memory blocks, and remove one, and fix start and length of the other to cover the memory area of both. Simple brute force way would be to traverse the free list, and test if the freed block can be merged with existing free block (either before or after), and then add it as last in the list if no suitable merge candidate was found.

    – hyde
    Nov 21 '18 at 15:25











  • After that works, you might want to check if the newly enlarged free block could now be merged too (in case the freed block filled a gap between two free blocks).

    – hyde
    Nov 21 '18 at 15:26













  • A more efficient solution would involve using some more advanced data structure (such as a tree of some kind) to hold the free blocks, so you wouldn't have to traverse the entire list to find possible merge candidates. Slight improvement could be achieved by keeping the free list sorted (which is basically free, since you need to traverse it anyway), so you can stop searching earlier.

    – hyde
    Nov 21 '18 at 15:29





















  • I don't get why you're comparing the next pointer to MAGIC and aborting if that's not what's there.

    – Thomas Jager
    Nov 21 '18 at 12:57











  • If you malloc a block the next element of this block is MAGIC. (lauf->next = MAGIC;) And in the free() you have to check if the element you want to free can be freed at all or if it is already free.

    – Nicooost
    Nov 21 '18 at 13:14











  • This is rather broad question. So you have a linked list, with list items representing memory blocks. And then you need to find the list items which point to adjacent memory blocks, and remove one, and fix start and length of the other to cover the memory area of both. Simple brute force way would be to traverse the free list, and test if the freed block can be merged with existing free block (either before or after), and then add it as last in the list if no suitable merge candidate was found.

    – hyde
    Nov 21 '18 at 15:25











  • After that works, you might want to check if the newly enlarged free block could now be merged too (in case the freed block filled a gap between two free blocks).

    – hyde
    Nov 21 '18 at 15:26













  • A more efficient solution would involve using some more advanced data structure (such as a tree of some kind) to hold the free blocks, so you wouldn't have to traverse the entire list to find possible merge candidates. Slight improvement could be achieved by keeping the free list sorted (which is basically free, since you need to traverse it anyway), so you can stop searching earlier.

    – hyde
    Nov 21 '18 at 15:29



















I don't get why you're comparing the next pointer to MAGIC and aborting if that's not what's there.

– Thomas Jager
Nov 21 '18 at 12:57





I don't get why you're comparing the next pointer to MAGIC and aborting if that's not what's there.

– Thomas Jager
Nov 21 '18 at 12:57













If you malloc a block the next element of this block is MAGIC. (lauf->next = MAGIC;) And in the free() you have to check if the element you want to free can be freed at all or if it is already free.

– Nicooost
Nov 21 '18 at 13:14





If you malloc a block the next element of this block is MAGIC. (lauf->next = MAGIC;) And in the free() you have to check if the element you want to free can be freed at all or if it is already free.

– Nicooost
Nov 21 '18 at 13:14













This is rather broad question. So you have a linked list, with list items representing memory blocks. And then you need to find the list items which point to adjacent memory blocks, and remove one, and fix start and length of the other to cover the memory area of both. Simple brute force way would be to traverse the free list, and test if the freed block can be merged with existing free block (either before or after), and then add it as last in the list if no suitable merge candidate was found.

– hyde
Nov 21 '18 at 15:25





This is rather broad question. So you have a linked list, with list items representing memory blocks. And then you need to find the list items which point to adjacent memory blocks, and remove one, and fix start and length of the other to cover the memory area of both. Simple brute force way would be to traverse the free list, and test if the freed block can be merged with existing free block (either before or after), and then add it as last in the list if no suitable merge candidate was found.

– hyde
Nov 21 '18 at 15:25













After that works, you might want to check if the newly enlarged free block could now be merged too (in case the freed block filled a gap between two free blocks).

– hyde
Nov 21 '18 at 15:26







After that works, you might want to check if the newly enlarged free block could now be merged too (in case the freed block filled a gap between two free blocks).

– hyde
Nov 21 '18 at 15:26















A more efficient solution would involve using some more advanced data structure (such as a tree of some kind) to hold the free blocks, so you wouldn't have to traverse the entire list to find possible merge candidates. Slight improvement could be achieved by keeping the free list sorted (which is basically free, since you need to traverse it anyway), so you can stop searching earlier.

– hyde
Nov 21 '18 at 15:29







A more efficient solution would involve using some more advanced data structure (such as a tree of some kind) to hold the free blocks, so you wouldn't have to traverse the entire list to find possible merge candidates. Slight improvement could be achieved by keeping the free list sorted (which is basically free, since you need to traverse it anyway), so you can stop searching earlier.

– hyde
Nov 21 '18 at 15:29














0






active

oldest

votes











Your Answer






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: "1"
};
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: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53412469%2fown-free-in-c-melt-free-data-blocks%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


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


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53412469%2fown-free-in-c-melt-free-data-blocks%23new-answer', 'question_page');
}
);

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







這個網誌中的熱門文章

Tangent Lines Diagram Along Smooth Curve

Yusuf al-Mu'taman ibn Hud

Zucchini