当前位置:网站首页>[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;
}

边栏推荐
- Regular expressions in JS
- (p27-p32) callable object, callable object wrapper, callable object binder
- Map the world according to the data of each country (take the global epidemic as an example)
- (p25-p26) three details of non range based for loop and range based for loop
- Hands on learning and deep learning -- Realization of linear regression from scratch
- How to write simple music program with MATLAB
- MYSQL中的调用存储过程,变量的定义,
- 对企业来讲,MES设备管理究竟有何妙处?
- 后MES系统的时代,已逐渐到来
- MYSQL中的触发器
猜你喜欢

How to write simple music program with MATLAB

数据库基础——规范化、关系模式

ctfshow web 1-2

(p27-p32) callable object, callable object wrapper, callable object binder

模型压缩 | TIP 2022 - 蒸馏位置自适应:Spot-adaptive Knowledge Distillation

MATLAB image processing - Otsu threshold segmentation (with code)

工厂的生产效益,MES系统如何提供?

ctfshow web4

Py&GO编程技巧篇:逻辑控制避免if else

Prediction of COVID-19 by RNN network
随机推荐
FPGA implementation of right and left flipping of 720p image
Error: clear the history in the search box in the website?
Hands on learning and deep learning -- a brief introduction to softmax regression
Calling stored procedures in mysql, definition of variables,
A brief summary of C language printf output integer formatter
网站Colab与Kaggle
三国杀周边--------猪国杀题解
MYSQL中的触发器
Hands on deep learning -- implementation of multi-layer perceptron from scratch and its concise implementation
Where does the driving force of MES system come from? What problems should be paid attention to in model selection?
MYSQL中的锁的机制
Strvec class mobile copy
What is the quality traceability function of MES system pursuing?
Never use MES as a tool, or you will miss the most important thing
Py & go programming skills: logic control to avoid if else
Vision transformer | arXiv 2205 - TRT vit vision transformer for tensorrt
js中的数组
The residual pressure monitoring system ensures the smoothness of the fire evacuation passage in case of fire, and protects the safe operation of large high-rise buildings and the safety of people's l
GTEST/GMOCK介绍与实战
Easyexcel exports excel tables to the browser, and exports excel through postman test [introductory case]