C Review of Systematic Learning (11) Dynamic Memory Management

In the c language, we focus on what exists in the memory: (There are other areas besides this)
stack area
local variables
Formal parameters of the function (parameters)
heap area
        malloc/free
        calloc
        realloc
Dynamic memory allocation
static area
`` global variables
static variable (const)

The four main functions of dynamic memory management

#include <stdlib.h> //Dynamic memory header file

mallco and free

void* malloc(size_t size);
This function applies for a contiguous available space from memory and returns a pointer to this space.
void free (void* ptr);
If the space pointed to by the parameter ptr is not dynamically allocated, the behavior of the free function is undefined.
If the parameter ptr is a NULL pointer, the function does nothing.

int main()
{
	int* ptr = (int*)malloc(40);	//malloc applied for 40 bytes to the heap area and returned void* type. We cast to type int*
	int* p = ptr;	//Make sure that the starting address of the requested space is not lost
	if (p == NULL)
	{
		perror("malloc"); //If the development fails, use perror to return the error reason
		return 1;
	}
	//memset(p, 0, 40); //Initialize the space of 40 bytes starting from p address
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*p = i;
		p++;
	}//Here is the space initialization of 40 bytes requested
	//If you don't need the space after using it, free up the space free
	free(ptr);	//Release from the starting address of the requested space, so ptr is required
	ptr = NULL; //After release, ptr becomes a wild pointer and is set to NULL

	return 0;
}

calloc

void* calloc(size_t num, size_t size);
Used to apply for memory and initialized to 0

int main()
{
	int* p = (int*)calloc(10, sizeof(int));
	if (p == NULL)
	{
		perror("calloc");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p + i));
	}
	free(p);
	p = NULL;
	return 0;
}


realloc

void* realloc (void* ptr, size_t size);
Adjust the size of the requested memory space

int main()
{
	int* p = (int*)malloc(40);	
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(p+i) = i;
	}
	//When the space is not enough, I hope that 20 elements can be placed, and realloc is needed to expand the capacity
	int* ptr = (int*)realloc(p, 80);//The whole becomes 80 bytes. instead of appending 80 bytes	
	//Here are two situations
	if (ptr != NULL)
	{
		p = ptr;
	}
	//The expansion is successful, start using it.
	
	//No longer use
	free(p);
	p = NULL;

	return 0;
}

The above two situations:

1. If the subsequent space is sufficient for expansion, then continue to expand the space after the address of p
p[][][][][][][] (later expansion) [][][][][][][]
2. If the subsequent space is not enough to expand, then it will look for a sufficient space elsewhere in the memory, transfer the content of p to the new space and continue to expand, and will free the original space of p at the same time, so in order to prevent The capacity expansion failed (not enough space could be found) and the original space was released, perform int* ptr = realloc(p,80); to ensure success and then assign ptr to p

Common memory errors

1. Dereferencing a null pointer
Solution: Make a null pointer judgment on the return value of the malloc function
    if (p == NULL)
    {
perror("malloc"); //If the allocation fails, use perror to return the error reason
        return 1;
    }
2. Out-of-bounds access to dynamic memory opening space
3. Use free to release non-dynamically allocated memory
4. Use free to release part of a dynamically allocated memory
5. Release the same piece of dynamic memory multiple times
    void test()
    {
        int *p = (int *)malloc(100);
        free(p);
free(p);//repeated release
    }
6. Dynamically open up memory and forget to release it (memory leak)

classic interview questions

void GetMemory(char* p)
{
	p = (char*)malloc(100);
}
void main(void)
{
	char* str = NULL;
	GetMemory(str);
	if (str == NULL)
	{
		perror("malloc");
	}
	strcpy(str, "hello world");
	printf(str);
}
run error, p is a formal parameter. after the end str Still a null pointer.
Error type: dereference to null pointer, program crashes
 Modified to be correct:
void GetMemory(char** p)
{
	*p = (char*)malloc(100);
}
void main(void)
{
	char* str = NULL;
	GetMemory(&str);
	if (str == NULL)
	{
		perror("malloc");
	}
	strcpy(str, "hello world");
	printf(str);
}

Tags: C programming language

Posted by karldenton on Tue, 07 Feb 2023 05:57:39 +1030