Deepak
Deepak

Reputation: 1545

how to free allocated memory inside a function by passing correct pointer to free()

In function "create_memory_pool" I can allocate pools of memory but I am not sure how can I free it from main program.

I think I am missing how to pass correct pointer from function to free by which I can free the memory allocated previously.

Note i can not change the parameters passed to function create memory pool(not allowed). but can change the content inside the function.

#include <stdio.h>
#include <stdlib.h>

typedef enum {
   false,
   true
} boolean;

boolean create_memory_pool(char *name, int size)
{
  name = malloc(size);
  if (name != NULL)
    {
      printf("malloc successful\n");
      return true;
    }
  else
    {
      printf("malloc failed\n");
      return false;
    }
}

int main()
{
  boolean rc;
  char *name;


  // case 2
  rc = create_memory_pool(name, 1024);
  free(name);

  return 0;
}

Upvotes: 0

Views: 500

Answers (3)

Adrian Panasiuk
Adrian Panasiuk

Reputation: 7343

You claim you must adhere to the following prototype

boolean create_memory_pool(char *name, int size);

Given this prototype, it is obvious that create_memory_pool is not supposed to allocate its own memory, but the caller is obligated to provide a block of memory.

What the create_memory_pool does instead, is it creates the necessary book keeping inside the block, that allows it to be used as a memory pool (from which, I suppose, you can allocate smaller fixed-sized blocks, with a different function prototyped in the header.)

/**
 * Initialize a memory pool in {@code name}, which has size {@code size}.
 */
boolean create_memory_pool(char *name, int size)
{
    // the initial bytes of {@code memory_pool} are the header
    struct memory_pool *pool = (struct memory_pool*) name;
    initialize stack pool->stack;
    divide the remainder of the memory block after the header into blocks of size BLOCK_SIZE and add to the stack pool->stack;
}

/**
 * Allocate a block of size {@code BLOCK_SIZE} in the memory pool {@code memory_pool} or return null on failure.
 */
void *alloc_block(char *poolopaque)
{
    struct memory_pool *pool = (struct memory_pool*) poolopaque;
    pop and return a block from pool->stack or return null;
}

/**
 * Return a block of memory into the memory pool.
 */
void free_block(char *poolopaque, void *block)
{
    struct memory_pool *pool = (struct memory_pool*) poolopaque;
    add block to pool->stack
}

Upvotes: 1

You function create_memory_pool is not exposing any pointer.

You must change it from:

boolean create_memory_pool(char *name, int size)
{
  name = malloc(size);
  if (name != NULL)
    {
      printf("malloc successful\n");
      return true;
    }
  else
    {
      printf("malloc failed\n");
      return false;
    }
}

To

boolean create_memory_pool(char **name, int size)
{
  *name = malloc(size);
  if (*name != NULL)
    {
      printf("malloc successful\n");
      return true;
    }
  else
    {
      printf("malloc failed\n");
      return false;
    }
}

And in your main, change the call at case 2 to:

rc = create_memory_pool(&name, 1024);

Your whole case 1 doesn't make sense at all.

You should review how pointers works.

Upvotes: 5

rodrigo
rodrigo

Reputation: 98348

Pointers don't work like you think. The name you are passing to create_memory_pool is useless. And if you want to return the allocated memory... well, you have to return it.

char *create_memory_pool(int size)
{
  char *ptr = malloc(size);
  if (ptr != NULL)
    {
      printf("malloc successful\n");
      return ptr;
    }
  else
    {
      printf("malloc failed\n");
      return NULL;
    }
}

But then, this function does little more than calling malloc, so you could remove it all together.

Actually, a function can return -sort of- several values, but all but one must use pass-by-pointer arguments:

boolean create_memory_pool(char **ptr, int size)
{
    *ptr = malloc(size);
    if (*ptr != NULL)
    {
      printf("malloc successful\n");
      return true;
    }
    ...
}

Some of your confusion seems to arise from the fact that in C string literals are pointers, and pointers are used to manage dynamic memory. But that doesn't mean that string literals are used to refer to dynamic memory!

Upvotes: 1

Related Questions