[C] Dynamic Memory Management

When you create a variable in C, it is created in stack. You do not need to allocate or free the memory for a variable specifically. Though when you work with large struct data types, this approach might not be efficient. You can allocate memory and free it dynamically.

 

1. Memory Management in C# and Java

In object oriented languages, objects are main building blocks. When you create objects, they are located in heap, which means that the memory should be allocated and freed for those objects.

C# and Java runtime do this memory management tasks for you. The memory is allocated when the object is created and Garbage Collector automatically frees the memory of unused objects.

In C, you need to do them by yourself.

 

2. Getting the Memory

The “malloc()” function is used to allocate the memory for data. The “stdlib.h” file should be included.

#include <stdlib.h>
  • void *malloc(size_t size)

The “malloc()” is almost always used with the “sizeof()” operator. It is the best way to determin the size of required memory. It returns the pointer to void. What does it? It is called a void pointer (void *) or a general-purpose pointer, which indicates that it is a pointer to an unknown (or any) data type.

int *p;
p = malloc(sizeof(int));

 

3. Freeing up the Used Memory

When you do not need to use data, the memory should be freed.

  • If you do not free the memory, the so-called memory leak occurs. The application will eventually used up all free memory and will not work.
  • Do not access the memory using the pointer once it is freed. The application will crash.

The “free()” method is used to free the memory.

  • void  free(void *p)
free(p);

 

4. Example

typedef struct
{
  char *Name;
  int Age;
} Person;

void TypeTest1()
{
  Person *homer = malloc(sizeof(Person));

  homer->Name = "Homer Simpson";
  homer->Age = 36;

  printf("Name = %s, Age = %i n", homer->Name, homer->Age);

  free(homer);
}

In C++, you do need to cast the result of “malloc()” to the right type. In C, you do not need to cast.

Person *homer = (Person *) malloc(sizeof(Person)); /* C++ */

 

5. String Copy

Let’s run the following code.

Person *Create(char *name, int age)
{
  Person *p = (Person *) malloc(sizeof(Person));
  p->Name = name;
  p->Age = age;
  return p;
}

void TypeTest5()
{
  char name[80] = "Homer Simpson";

  Person *homer = Create(name, 36);

  strcpy(name, "Bart Simpson");
  Person *bart = Create(name, 10);

  printf("Name = %s, Age = %i n", homer->Name, homer->Age); /* Bart Simpson, 36 */
  printf("Name = %s, Age = %i n", bart->Name, bart->Age); /* Bart Simpson, 10 */

  free(homer);
  free(bart);
}

The code looks good but what about the result? Where is “Homer Simpson” gone?

The problem is when a person is created, name pointer just points to the address of “char name[80]”. It does not matter how many persons are created. They all point to the only one address.

You might ask “Wait a minute. I called malloc() for the “Person” struct and assigned the memory for the Name”. The malloc() does not create a memory space for the name memeber (the size of the name is even not known yet). It just create a pointer (4 or 8 bytes).

Therefore you need to allocate a memory for “Name” and assign the address to the pointer. You can use “malloc” again but C library already provides a useful function in “string.h“.

  • char *strdup(char *src);
Person *Create(char *name, int age)
{
  Person *p = (Person *) malloc(sizeof(Person));
  p->Name = strdup(name);
  p->Age = age;
  return p;
}

void TypeTest5()
{
  char name[80] = "Homer Simpson";

  Person *homer = Create(name, 36);

  strcpy(name, "Bart Simpson");
  Person *bart = Create(name, 10);

  printf("Name = %s, Age = %i n", homer->Name, homer->Age); /* HomerSimpson, 36 */
  printf("Name = %s, Age = %i n", bart->Name, bart->Age); /* Bart Simpson, 10 */

  free(homer->Name);
  free(homer);
  free(bart->Name);
  free(bart);
}

There is one more change. Now the name is created by malloc() so you need to free the memory.

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s