Dynamic memory management notes

Why is there dynamic memory management?

  1. Under different requirements, the space may need to be adjusted continuously, resulting in a decrease in the scalability of the code.
  2. It may be that the space division is unreasonable, which may lead to a waste of space.
  3. Generally, on the stack, the space that can be effectively allocated at one time is limited.

For the above reasons, dynamic memory management is required. The benefits of dynamic memory management are:

  1. Let us decide the size of the open space during the running of the program. Give as much as you apply.
  2. Use space efficiently. Will not cause a waste of space.
  3. There is more space available. Heap space>stack space.

Dynamic memory management is to apply for space in the heap area, and the applied space is continuous.
On the stack, the stack: automatic application, automatic release. Users do not need to perform dynamic memory management.
Heap space: You need to apply for space yourself, and release it yourself: free.

 
 
 
malloc function

原型:void * malloc(size_t size);

The malloc function applies for a continuous available space from the memory and returns a pointer to this space.

  • If the development is successful, return a pointer to this address
  • If the development fails, a NULL pointer is returned, so the return value must be checked
  • The type of the return value is void*, which can be forced according to our needs

Free function : specifically used to release and recover dynamic memory.

原型:void free(void *ptr)

  • If ptr is not developed by dynamic memory, then operations such as the free function are undefined
  • If ptr is a NULL pointer, the function will not work

If the requested space is not free (forgot to free): it will cause a memory leak.
Memory leaks can cause system memory to decrease. If the program exits, the memory leak will automatically recover and the memory will be returned to the system.

Programs that are running most of the time should pay special attention to memory leaks.

A pointer points to a space that has no use permission. Such pointers are called wild pointers (dangling pointers).

int main()
{
	int num = 5;
	int *ptr = NULL;
	ptr = (int *)malloc(sizeof(int)*num);
	if (NULL == ptr)
	{
		exit(EXIT_FAILURE);
	}
	printf("%p\n", ptr);
	free(ptr);
	printf("%p\n", ptr);
	return 0;
}

Insert picture description here
After free, ptr still points to the address, but the pointer does not have permission to operate on the address.

calloc function

void *calloc(size_t num,size_t size);

  • Create a space for num elements of size size, and initialize each section of the space to 0

Compared with the malloc function:

The space requested by malloc will not be initialized. (Maybe faster, because less work has been done)
The space requested by calloc will be initialized. (By byte, initialized to 0)

When applying for space, generally the actual size of the application is larger than the required memory space size: for
example, 8 bytes of space are required, which is actually larger than 8.
why?

  1. The extra space is not for users to use, but for system management.
  2. After freeing the space, free will not empty ptr. Only an address is released. But after it is released, it cannot be used, and an error will be reported if it is used again. What is released is the correspondence between pointers and addresses.

 
 
In dynamic memory management, the entire application must be applied and released as a whole . Do not make changes to the pointer.

realloc function

void *realloc(void *ptr,size_t size)

  • ptr is the memory address to be adjusted
  • size is the adjusted size
  • The return value is the starting address after adjustment

How to adjust?
There are two situations for realloc function adjustment:

  1. Expansion:

Direct expansion: the original space is large enough, it can be expanded directly, and the return value is the same.
Reopen: (the original space is insufficient), reopen the space, and return to the new address
Insert picture description here

int main()
{
	int num = 5;
	int *ptr = NULL;
	ptr = (int *)malloc(sizeof(int)*num);
	if (NULL == ptr)
	{
		exit(EXIT_FAILURE);
	}
	printf("%p\n", ptr);
	int *ret = realloc(ptr, 10000);
	if (NULL != ret)
	{
		ptr = (int *)ret;
	}
	printf("%p\n", ptr);
	free(ptr);
	return 0;
}

Insert picture description here

2. Shrinking: just shrink directly.

When using the realloc function, you cannot use it like this: directly assign the re-applied space to the old pointer.
Doing so will cause, if the development fails, the return will be NULL, the original space will be set to NULL, and this space will no longer be found. The pointer is also missing. The heap space will be lost, causing a memory leak. A decision can be used to decide whether to do so. Just like the code above.

After the realloc function is executed, the newly applied space is used, including free. And no longer use the old space, free does not release the old space.

 
 
 

A more interesting question:

char *GetMemory(void)
{
	char p[] = "hello world";
	return p;
}
void test()
{
	char *str = NULL;
	str = GetMemory();
	printf(str);
}

The GetMemory function returns the starting address of p, which is released when it is adjusted. However, the address of the p array, its data still exists.
This is the same as storing a file on a computer. When a file is deleted, the permission to use this block is deleted. The file is invalid, but its data still exists. Data recovery is based on this nature.
Finally, when the printf function is called, a new stack frame structure is formed, which will overwrite this data. Therefore, the output of this code is garbled.

 
 
 
 
In dynamic memory management, pay more attention to:

  1. The requested space must be verified. (Whether the development is successful)
  2. After use, it must be released. (Otherwise it will cause a memory leak)
  3. Don't cross the border to visit.
  4. Free must release the space opened up by dynamic memory, not on the stack.
  5. The starting position cannot be changed, nor can it be partially released.
  6. Don't release it multiple times (after the first release, the pointer has no operation authority on the space, and if you release it again, an error will occur).

Guess you like

Origin blog.csdn.net/w903414/article/details/106943162