当前位置:网站首页>[dynamic memory management] malloc & calloc and realloc and written test questions and flexible array
[dynamic memory management] malloc & calloc and realloc and written test questions and flexible array
2022-06-12 08:28:00 【Always brush questions every day】
0 Why dynamic memory management exists ?
char str[20]={0];
int arr[20]={0};The above-mentioned way of space development has two characteristics :
- The size of space is fixed
- When declaring an array, you must specify the size of the array space , It allocates the required memory at compile time
But if the amount of space we need is uncertain at the time of program compilation , It's not until the program runs , Then the above-mentioned way of space development is not suitable , Dynamic memory management came into being .
Define the difference between local variable memory and dynamic memory :
- Where to open up space :
- Define the space opened up by local variables : Random position on stack
- Dynamic application space : Continuous position on the stack
- Release :
- Define the space opened up by local variables : Automatic destruction of outgoing code blocks
- Dynamic application space : It is better for the programmer to release manually
1 malloc function
The function prototype :void* malloc(size_t size)
Parameter description :size For the size of memory space to be allocated , Unit is byte

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
int main()
{
// The function prototype :void* malloc(size_t size)
// Applied to memory 40 Bytes of space :
// If the application is successful, the first address of this space will be returned
// If the application fails, a null pointer is returned NULL
int* p1 = (int*)malloc(40);// The development was successful
int* p2 = (int*)malloc(INT_MAX+1);// This development failed
// When you use this space later, it will change p The direction of , So use ptr Keep the starting address of this space
int* ptr = p1;
// Check pointer p The effectiveness of the : Check whether the return value of the memory request result is NULL
if (p· == NULL)
{
perror("malloc");//malloc: Not enough space
exit(-1);
}
// Opens the 40 Bytes , That is to say 10 individual int The size of the type variable
for (int i = 0; i < 10; i++)
{
*(p·++) = 0;
}
// Release ptr The space pointed to by the pointer , however ptr The starting address of the space for dynamic application is still reserved
free(ptr);
// Give Way ptr Pointing empty , Make him lose the memory of the starting address of the space dynamically applied for
ptr = NULL;
p=NULL;
return 0;
}When we do not manually free the space opened up by dynamic memory :
- If the program ends , The dynamically requested memory consists of OS Automatic recovery
- But if the program never ends , The space requested by dynamic memory will not be released automatically , It will cause memory leakage problems . ( The memory of dynamic application will be automatically released after the program ends , Otherwise, the memory will be less and less , Who dares to write code ; But when this space takes up too long , And this space is relatively large , Will compare to eat memory )
2 calloc function
The function prototype :void* calloc(size_t num,size_t size)
Parameter description :num Is to assign size The number of elements in a space of bytes

malloc and calloc The difference between : calloc When applying for memory space, initialize this space to 0 了
int main()
{
// The function prototype : void* calloc(size_t num,size_t size)
// Element number :10
// The number of bytes per element :sizeof(int)
int* p = (int*)calloc(10, sizeof(int));
int* ptr = p;
if (p == NULL)
{
perror("calloc");
exit(-1);
}
for (int i = 0; i < 10; i++)
{
printf("%d\t", *(p++));
}
free(ptr);
ptr = NULL;
p = NULL;
}
3 realloc function
With realloc function , We can already malloc or calloc Readjust the space that has been opened up and is not satisfied with the capacity .( adjustment : You can turn it up or down )
Reallocate memory space function :void* realloc(void* ptr,size_t size)
Parameter description :ptr To point to the space that needs to be reallocated ,size For the amount of space that needs to be reallocated , Unit is byte .
Let's take capacity expansion as an example :
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
perror("malloc");
exit(-1);
}
for (int i = 0; i < 10; i++)
{
*(p + i) = i;//p No change of direction
}
// Hope to put 20 Elements , Space is not enough , Consider using realloc Capacity expansion
int p = (int*)realloc(p, 80);//error, In case realloc Expansion failed ,p A null pointer was received , Turn the original p Directional coverage of ( lose ) 了
// The function prototype :void* realloc(void* ptr,size_t size)
//ptr: A pointer , The pointer points to the starting address of the expanded space
//size: The number of bytes expected after successful expansion
int* temp = (int*)realloc(p, 80);//bingo
if (temp != NULL)
{
p = temp;
}
free(p);
p = NULL;
return 0;
}realloc Adjust the space :
- If you want to reduce the space : Then the space of corresponding length is intercepted on the original space , And return the original first address ( It's equal to p)
- If it is to expand space , Below 3 In this case :
- If the location of the original space in the memory can open up the required space after the expansion , We will open up accordingly , And return the starting address of the new space .
- If the location of the original space in the memory cannot open up the space required after the expansion ,OS You will find a new space in the heap memory that is large enough to hold the required space , Copy the values in the original space to the new space , And return the starting address of the new space
- If any location in the heap memory is not enough to open up the required memory space , Return null pointer .
4 Common dynamic memory errors
int main()
{
//way1: Yes NULL Pointer to dereference
int* p = (int*)malloc(INT_MAX + 1);
// Use it directly //error
//way2: A cross-border visit
int* p = (int*)malloc(40);
if (p == NULL)
{
perror("malloc");
exit(-1);
}
for (int i = 0; i < 11; i++)//error
{
*(p + i) = i;
}
//way3: Use free Function to free non dynamically requested memory
int a = 10;
int* p = &a;
free(p);//error
p = NULL;
//way4: Use free Function to free a portion of the dynamically requested memory
int* p = (int*)malloc(40);
if (p == NULL)
{
perror("malloc");
exit(-1);
}
for (int i = 0; i < 11; i++)//error
{
*p = i;
p++;
}
free(p);//error
p = NULL;
//way5: The memory of the same dynamic request is released multiple times
free(p);
free(p);
p = NULL;
//way6: Forget to free the memory of dynamic application
return 0;
}5 2 A classic written test question :
Pen test 1: The following code can print out hello world Do you ?------> Value and address
// Error code :
void Getmory(char* p)
{
p = (char*)malloc(100);
}
void test(void)
{
char* str = NULL;
Getmory(str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
test();
return 0;
}answer : You can't , According to the original meaning of the code : Want to pass Getmory Function gives str Dynamic development for a period 100 Bytes of space , And then use strcpy Function copies the string ‘hello world’ And print it out .
The problem lies in :Getmory The function parameter of a function is just a character pointer str A temporary copy of , The change of formal parameters p Does not affect arguments str, And in that case ,p The space pointed to is p No code block has been released , Out Getmory After the function code block , local variable p Be destroyed , The space of this dynamic application has not been destroyed , Can no longer be destroyed .
in addition , chain reaction ,str Or point to empty ,strcpy When the function is executed, the source space is insufficient "hello world“
, There will be a second problem .
Correct code :
// Correct code :
void Getmory(char** p)
{
*p = (char*)malloc(100);
}
void test(void)
{
char* str = NULL;
Getmory(&str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
test();
return 0;
}

Pen test 2: The following code can print out "hello world“ Do you ”-------->“ Return stack space address problem ”
// Error code :
char* Getmory(void)
{
char p[] = "hello world";
return p;
}
void test()
{
char* str = NULL;
str = Getmory();
printf(str);
}
int main()
{
test();
return 0;
}answer : You can't ,Getmory Function ,"hello world” Is placed in a character array , When returned, the array name is returned , That is, the address of the first element of the array ,Getmory The space occupied by the character array is automatically destroyed at the end of the function , But it returns the address of the stack space , Once in a test Function to access the address dereference , That's illegal , Unknown , The error cause of the above code is similar to that of the following code .
// Error code
int* test()
{
int a = 10;
return &a;
}
int main()
{
int* p=test();
*p = 10;
printf("%d\n", *p);
printf("%d\n", *p);
return 0;
}6 Flexible array
Flexible array : The last element in the structure is allowed to be an array of unknown size , This is the same as 【 Flexible array 】 member .
struct s
{
int num;
double e;
int arr[0];
// or int arr[0];
};The characteristics of flexible arrays :
- A flexible array member in a structure must be preceded by at least one other non flexible array member .
- The memory size of the structure containing the flexible array does not include the memory size of the flexible array .
- Structures containing flexible arrays must be used when opening up memory malloc Function dynamic memory development , And the open space must be larger than the size of the structure , To accommodate the expected size of the flexible array .
struct s
{
int num;
int arr[0];
// or int arr[0];
};
int main()
{
printf("sizeof(struct s):>%d\n", sizeof(struct s));
struct s* ps = (struct s*)malloc(sizeof(struct s) + 40);
ps->num = 100;
for (int i = 0; i < 10; i++)
{
ps->arr[i] = i;
}
for (int i = 0; i < 10; i++)
{
printf("%d\t", ps->arr[i]);
}
return 0;
}
struct s
{
int num;
int arr[0];
// or int arr[0];
};
int main()
{
printf("sizeof(struct s):>%d\n", sizeof(struct s));
struct s* ps = (struct s*)malloc(sizeof(struct s) + 40);
if (ps == NULL)
{
perror("malloc");
exit(-1);
}
ps->num = 100;
for (int i = 0; i < 10; i++)
{
ps->arr[i] = i;
}
for (int i = 0; i < 10; i++)
{
printf("%d\t", ps->arr[i]);
}
// The flexible meaning of flexible array : Sure realloc Capacity expansion
struct s* temp = (struct s*)realloc(ps, sizeof(struct s) + 80);
if (temp != NULL)
{
ps = temp;
}
for (int i = 0; i < 20; i++)
{
ps->arr[i] = i;
}
for (int i = 0; i < 20; i++)
{
printf("%d\t", ps->arr[i]);
}
free(ps);
ps = NULL;
return 0;
}

边栏推荐
- Easyexcel exports excel tables to the browser, and exports excel through postman test [introductory case]
- Vision Transformer | Arxiv 2205 - TRT-ViT 面向 TensorRT 的 Vision Transformer
- EasyExcel导出Excel表格到浏览器,并通过Postman测试导出Excel【入门案例】
- What is the difference between ERP production management and MES management system?
- ASP.NET项目开发实战入门_项目六_错误报告(自己写项目时的疑难问题总结)
- (P17-P18)通过using定义基础类型和函数指针别名,使用using和typedef给模板定义别名
- 三国杀周边--------猪国杀题解
- 智能制造的时代,企业如何进行数字化转型
- 工厂的生产效益,MES系统如何提供?
- (p17-p18) define the basic type and function pointer alias by using, and define the alias for the template by using and typedef
猜你喜欢

Error: what if the folder cannot be deleted when it is opened in another program

In the era of intelligent manufacturing, how do enterprises carry out digital transformation

企业为什么要实施MES?具体操作流程有哪些?

Database foundation -- normalization and relational schema

ctfshow web3

(p19-p20) delegate constructor (proxy constructor) and inheritance constructor (using)

Installation series of ROS system (I): installation steps

安科瑞电动机保护器具有过载反时限、过载定时限、接地、起动超时、漏电、欠载、断相、堵转等功能

报错:文件夹在另一个程序中打开无法删除怎么办

Model compression | tip 2022 - Distillation position adaptation: spot adaptive knowledge distillation
随机推荐
What is the quality traceability function of MES system pursuing?
工厂的生产效益,MES系统如何提供?
(P13) use of final keyword
MSTP的配置与原理
What is the difference between ERP production management and MES management system?
后MES系统的时代,已逐渐到来
MES系统质量追溯功能,到底在追什么?
ASP.NET项目开发实战入门_项目六_错误报告(自己写项目时的疑难问题总结)
Hands on deep learning -- activation function and code implementation of multi-layer perceptron
You get download the installation and use of artifact
建立MES系统,需要注意什么?能给企业带来什么好处?
(p33-p35) lambda expression syntax, precautions for lambda expression, essence of lambda expression
Vision transformer | arXiv 2205 - TRT vit vision transformer for tensorrt
安科瑞电动机保护器具有过载反时限、过载定时限、接地、起动超时、漏电、欠载、断相、堵转等功能
(P25-P26)基于非范围的for循环、基于范围的for循环需要注意的3个细节
ctfshow web4
Model compression | tip 2022 - Distillation position adaptation: spot adaptive knowledge distillation
Hands on deep learning -- implementation of multi-layer perceptron from scratch and its concise implementation
Face recognition using BP neural network of NNET in R language
x64dbg 调试 EXCEPTION_ACCESS_VIOLATION C0000005