109-Analysis of Dynamic Memory in C Language

Dynamic memory in C language

int a = 10;
//int arr[a];//error
int *arr = (int *)malloc(a*sizeof(int));//等同int arr[a];

Malloc, calloc, and realloc are all allocated memory. They are all functions in the stdlib.h library, but there are some differences.


The prototype of the malloc function * void malloc(unsigned int num_bytes);
num_byte is the size of the space to be applied for, and we need to calculate it manually, such as int *p = (int *)malloc(20 *sizeof(int)), if the compiler If the default int is 4 bytes storage, then the calculation result is 80Byte, apply for a continuous space of 80Byte at a time, and coerce the space base address to int type and assign it to the pointer p. At this time, the requested memory value is uncertain.


The prototype of the calloc function is void *calloc(size_t n, size_t size);
it has one more parameter than the malloc function and does not need to artificially calculate the size of the space. For example, if he wants to apply for 20 int type spaces, he will int *p = ( int *)calloc(20, sizeof(int)), which saves the trouble of artificial space calculation. But this is not the most important difference between them. The value of the space after malloc application is random and has not been initialized, while calloc initializes the space one by one after application and sets the value to 0;

Since the calloc function has to initialize the value for each space, the efficiency is lower than that of malloc. In many cases, the space application does not require the initial value.

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

int main()
{
    
    
	int *p = (int *)malloc(20*sizeof(int));
	int *pp = (int *)calloc(20, sizeof(int));
	int i;
	printf("malloc申请的空间值:\n\n");
	for ( i=0 ; i < 20; i++)
	{
    
    
		printf("%d ", *p++);
	}
	printf("\n\n");
	printf("calloc申请的空间的值:\n\n");
	for ( i=0 ; i < 20; i++)
	{
    
    
		printf("%d ", *pp++);
	}
	printf("\n");
	return 0;
}

Insert picture description here
The realloc function The
realloc function is essentially different from the above two. Its prototype void *realloc(void *ptr, size_t new_Size) is
used to expand the dynamic memory and the applied dynamic space is not enough to use, and the space expansion operation is required), ptr It is a pointer to the original space base address, and new_size is the size to be expanded next.

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

int main()
{
    
    
	const int size = 2000;
	int *p = (int *)malloc(20*sizeof(int));
	int *pp = (int *)realloc(p, size*sizeof(int));
	printf("原来的p_Address:%x   扩容后的pp_Address:%x \n\n", p, pp);
	return 0;
}

Insert picture description here
It can be seen from the figure that the address after expansion is different from the original address, but this only depends on the size of the expanded memory.
Note that
if the size is small, and there is free memory behind the originally applied dynamic memory, the system will expand directly behind the original memory space and return to the original dynamic space base address; if the size is large, there is not enough space behind the originally applied space for expansion , The system will reapply for a piece of (20+size)*sizeof(int) memory, and copy the contents of the original space, the original space is free; if the size is very large, the system memory application fails and returns NULL, and the original memory will not freed. Note: If the expanded memory space is smaller than the original space, data loss will occur. If you directly realloc(p, 0); equivalent to free( p)

free: Release dynamic memory. If it is not released, memory leaks (a very troublesome problem for C/C++) will occur when the leaked
memory is recovered: 1. The process (the running program) ends; 2. Shut down

Paste the practice code below

int main()
{
    
    
	int n;
	scanf("%d",&n);
	int *arr = (int *)malloc(n*sizeof(int));
	int i;
	for(i=0;i<n;i++)//模拟arr被使用了
	{
    
    
		arr[i] = i;
	}
	//容量不够,需要扩容到原来的2倍
	/*
	int *brr = (int *)malloc(2*n*sizeof(int));//创建更大的内存
	for(i=0;i<n;i++)//搬新家
	{
		brr[i] = arr[i];
	}
	free(arr);//释放原来的内存
	
	arr = brr;brr = NULL;//更新新的地址//继续使用arr
	*/
	printf("%d\n",arr);
	//下面的这一句代码等同上面
	arr = (int *)realloc(arr,n/2*sizeof(int));
	printf("%d\n",arr);
	free(arr);
	return 0;
}
int main()
{
    
    
	int n;
	scanf("%d",&n);
	//申请n个长度的int数组,并将每个元素置0
	int *arr = (int *)malloc(n*sizeof(int));
	/*for(int i=0;i<n;i++)
	{
		arr[i] = 0;
	}*/
	//上面的代码和下面这一句等价
	//int *arr = (int *)calloc(n,sizeof(int));
	for(int i=0;i<n;i++)
	{
    
    
		printf("%d ",arr[i]);
	}
	//int x;
	//printf("\n%d\n",x);

	char *brr = (char *)malloc(10*sizeof(char));
	char crr[10];
	printf("%s\n%s\n",brr,crr);

	return 0;
}
//大内存
int main()
{
    
    
	//char arr[1024*1024];//1M,定义不成功
	char *arr = (char *)malloc(1024*1024*sizeof(char));
	assert(arr != NULL);
	printf("haha\n");
	return 0;
}

Guess you like

Origin blog.csdn.net/LINZEYU666/article/details/111564806