C Memory management functions

The C language provides several functions for memory allocation and management. These functions can be found in the <stdlib.h> header file.

The serial number Functions and descriptions
1 void calloc(int num, int size); Dynamically allocate num contiguous space of size in memory and initialize each byte to 0. So it ends up assigning numSize Specifies the memory space in bytes, and each byte has a value of 0.
2 void free(void *address); This function frees the memory block pointed to by address, freeing dynamically allocated memory.
3 void *malloc(int num); Allocate a specified amount of memory in the heap to store data. This chunk of memory is not initialized after the function completes execution, and its value is unknown.
4 void *realloc(void *address, int newsize); This function reallocates memory, expanding it to newsize.

C speech inside the memory partition

  • Stack area (stack memory, storage of local variables, automatic allocation and release, function parameters inside, temporary variables inside methods)
  • The maximum heap size (dynamic memory allocation, manually allocated by programmers in C voice) is 80% of the operating system
  • Global area or static area
  • Constant area (string)
  • Program code area

Static and dynamic memory allocation

During the running of the program, the size of memory to be used is dynamically specified and released manually. After released, the memory can be reused.

Static memory allocation, allocation of memory size is fixed, resulting in problems:
1. It is easy to exceed the maximum stack memory
2. In order to prevent insufficient memory will open up more memory, easy to waste memory.
Dynamic memory allocation. During the running of a program, the amount of memory that needs to be used is dynamically specified, manually released, and then reused

Stack overflow

The following code causes a stack overflow


void main(a){
    // Static memory allocation, allocated to the stack, Window each application stack is about 2M, the size is determined. It's related to the operating system.
    int a [1024 * 1024 * 10 * 4];
}
Copy the code
This static memory is defined as 40MB, and each application stack in the Window is approximately 2M. If you exceed this range, stack Overflow will be reported.

Dynamic memory allocation and freeing


// Storage allocation,40M
// Parameters: bytes KB M 10M 40M
/ / set up
int* p1 = (int*)malloc(1024*1024*10*sizeof(int));
/ / release
free(p1);
Copy the code

Dynamically specifying the size of an array through dynamic memory allocation

When the program is running too long, you can optionally open up a specified size of memory for use, equivalent to the Java collection


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

// Create an array, dynamically specifying the size of the array
void main(a) {
    // Static memory allocation creates arrays of fixed sizes
    //int i = 10;
    //int a[i];

    int len;

    printf(Enter the length of the array:);
    scanf("%d", &len);

    // Open up memory by len * 4 bytes
    int* p = (int*)malloc(len * sizeof(int));//p: the first address of the array

    int i = 0;
    for (; i < len; i++) {
        p[i] = rand() % 100;
        printf("%d,%#x\n", p[i], &p[i]);
    }

    // Manually release memory
    free(p);

    getchar(a); }Copy the code

Result output:

41,0x513f48 67,0x513f4c 34,0x513f50,0x513f54 69,0x513f58 24,0x513f5cCopy the code

Realloc is realloc

There are two cases of memory reallocation:

If you shrink the memory, the data will be lost

Expanded memory, (continuous)

1. If the current memory segment has required memory space, directly expand the memory space, realloc returns the original pointer
2. If there are not enough free bytes after the current memory segment, the first memory block in the heap that meets this requirement is used to copy the current data to the new location, and the original database is freed, and the new memory address is returned
3. If the application fails, NULL is returned, and the original pointer is still valid

void main(a) {
    int len;
    printf("First input array length:");
    scanf("%d", &len);

    // Open up memory by len * 4 bytes
    int* p = (int*)malloc(len * sizeof(int));//p: the first address of the array

    int i = 0;
    for (; i < len; i++) {
        p[i] = rand() % 100;
        printf("%d,%#x\n", p[i], &p[i]);
    }


    int addLen;
    printf("Enter the increased length of the array :");
    scanf("%d", &addLen);


    int* p2 = (int*)realloc(p, sizeof(int) * (len + addLen));
    if (p2 == NULL) {
        printf("Redistribution failed......");
    }

    printf("------------ new array -------------------\n");
    // reassign
    i = 0;
    for (; i < len + addLen; i++) {
        p2[i] = rand() % 200;
        printf("%d,%#x\n", p2[i], &p2[i]);
    }

    // Manually releasing memory p2 will also release memory P, because either P has been released when allocating memory p2, or p2 and P point to the same address area
    if(p2 ! =NULL) {
        free(p2);
        p2 = NULL;
    }
    getchar(a); }Copy the code

Result output:

Enter the length of the array for the first time: 5 41 34, 0, 0 67, 0 x5e4adc x5e4ad8 x5e4ae0 0 69, 0, 0 x5e4ae4 x5e4ae8 increase the length of the input array: 5 -- -- -- -- -- -- -- -- -- -- -- -- new array -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 124, 0 x5e4ad8 78,0x5e4adc 158,0 x5e4ae4 64,0x5e4ae8 105,0x5e4aec 145,0x5e4af0 81,0x5e4af4 27,0x5e4af8 161,0x5e4afcCopy the code

A few details about memory allocation

1. Do not release it more than once
2. After the release is complete (pointer still has value), set the pointer to NULL to indicate that the release is complete
3. Memory leak (p reassigned, then free, not really free memory)

Avoiding memory leaks

P is free before reassigning

Memory leak


void main(a){
    //40M
    int* p1 = malloc(1024 * 1024 * 10 * sizeof(int));
    //free(p1);
    //p1 = NULL;
    // Error, memory is not freed immediately
    printf("%#x\n",p1);

    //80M
    p1 = malloc(1024 * 1024 * 10 * sizeof(int) * 2);
    
    free(p1);
    p1 = NULL;

    getchar(a); }Copy the code

Open task Manager and see that there is a 40M memory leak.

Correct way to write:


void main(a){
    //40M
    int* p1 = malloc(1024 * 1024 * 10 * sizeof(int));
    free(p1);
    p1 = NULL;
    printf("%#x\n",p1);

    //80M
    p1 = malloc(1024 * 1024 * 10 * sizeof(int) * 2);
    
    free(p1);
    p1 = NULL;

    getchar(a); }Copy the code

Open task Manager, see only 0.3m memory, normal.