C++ pointer advancement: dynamically allocating memory

working principle

malloc is a function in the stdlib.h library, declared as void *__cdecl malloc(size_t _Size);

  • principle:

    malloc The function applies for a memory block that meets the demand along the free linked list (located in the memoryheap space) and allocates the memory block of the required size Return the rest to the user on the linked list;

    and returns a pointer to the first address of the memory area, which means the type of the pointer is void *, so we need to cast the pointer type;

  • Parameter:_Size is the size of space to be applied for, that is, the size of the requested memory needs to be filled in explicitly, such as n * sizeof(int);

  • Return value:malloc When the memory allocation fails, the NULL pointer is returned. You can use the return value to determine whether the allocation is successful;

  • mallocThe applied space will not be initialized;

free is also a function in the stdlib.h library, declared as void __cdecl free(void *_Memory);

  • freeThe function will connect the memory blocks released by the user to the free chain;

  • Parameter: pointer_Memory should point to the memory block allocated by malloc(), memory declared in other ways cannot be usedfree() ;

Specific use

Dynamically create one-dimensional array
 
 
 
 
  • size_t element_cnt = 10;
    int *arr = (int *)malloc(element_cnt * sizeof(int));
    free(arr)
    

size_t element_cnt = 10; int *arr = (int *)malloc(element_cnt * sizeof(int)); free(arr)

Dynamically create a two-dimensional array
 
 
 
 
  • size_t m = 10, n = 10;
    int **arr = (int **)malloc(m * sizeof(int *));
    for (int i = 0; i < m; i ++)
        arr[i] = (int *)malloc(n * sizeof(int));
    

size_t m = 10, n = 10; int **arr = (int **)malloc(m * sizeof(int *)); for (int i = 0; i < m; i ++) arr[i] = (int *)malloc(n * sizeof(int));

It should be noted that the two-dimensional array obtained in this way cannot guarantee that its space is continuous.

calloc

calloc is defined in the stdlib.h library and declared as void *__cdecl calloc(size_t _NumOfElements,size_t _SizeOfElements);

calloc give malloc Main distinction:

  • principle:

    calloc The function will initialize the applied space one by one to 0;

    Due to automatic initialization, calloc operates less efficiently than malloc;

  • Parameter:calloc has one more parameter NumOfElements, no need to manually calculate the space size;

realloc

realloc is defined in the stdlib.h library and declared as void *__cdecl realloc(void *_Memory,size_t _NewSize);, used to expand dynamic content

  • parameter:

    _Memoryis a pointer pointing to the original space;

    _NewSizeis the space size after expansion

  • return value:

    If there is enough continuous space after _Memory, expand the address pointed to by _Memory and return _Memory;< /span>

    If the space is not enough, allocate space according to _NewSize, copy the original data to the newly allocated memory space, and release the memory area pointed to by _Memory (Automatic release, no needfree), and return the first address of the newly allocated memory area;

  • Returns null pointer when allocation fails NULL;

  • If _NewSize is smaller than the original size, the end of the original data may be lost;

new / delete

working principle

new and delete are keywords in C++ and require compiler support to be used.

  • return value:

    When the memory allocation is successful,new returns a pointer of the object type, and the type strictly matches the object;

    new When memory allocation fails, bac_alloc exception will be thrown. If the exception is not caught, the program will exit abnormally;

  • new There is no need to explicitly fill in the requested memory size. new will allocate memory according to the type of new;

  • newThe allocated memory space is in the free storage area;

  • new sum delete support weight;

  • A piece of memory cannot be released twice or more;

    It is legal to use on null pointer nullptr;delete

application

dynamic instantiation
 
 
 
 
  • // 动态创建变量
    int *p = new int(1234);
    /* ... */
    delete p;
    

// 动态创建变量 int *p = new int(1234); /* ... */ delete p;

newThere are three steps when dynamically creating an object:

  1. Call the operator new function to allocate a sufficient memory space (usually the underlying default implementation is malloc) to store objects of a specific type;
  2. The compiler runs the corresponding constructor to construct the function and passes in an initial value;
  3. Returns a pointer to the object;

deleteThere are two steps when releasing object memory:

  1. Call the object's destructor;
  2. The compiler calls the operator delete function to release the memory space (usually the underlying default implementation is free);
 
 
 
 
  • // 开辟新的对象
    class A {
        int a;
    public:
        A(int a_) : a(a_) {}
    };
    
    int main() {
        A *p = new A(1234);
        /* ... */
        delete p;
    }
    

  • 12

// 开辟新的对象 class A { int a; public: A(int a_) : a(a_) {} }; int main() { A *p = new A(1234); /* ... */ delete p; }

{}The operator can be used to initialize a structure without a constructor. Except for the first time, using the {} operator can make the initialization form of the variable consistent.

 
 
struct ThreeInt {
  int a;
  int b;
  int c;
};

int main() {
  ThreeInt* p = new ThreeInt{1, 2, 3};
  /* ... */
  delete p;
}

struct ThreeInt { int a; int b; int c; }; int main() { ThreeInt* p = new ThreeInt{1, 2, 3}; /* ... */ delete p; }

Create array dynamically

To create and release an array, you need to use new[] and delete[], and the new[] operator will return the first address of the array.

 
 
 
 
  • size_t element_cnt = 5;
    int *p = new int[element_cnt];
    /* ... */
    delete[] p;
    

size_t element_cnt = 5; int *p = new int[element_cnt]; /* ... */ delete[] p;

Dynamically create a two-dimensional array

There are three ways to dynamically create a two-dimensional array:

  1. declares a one-dimensional array with a length of N * M, and accesses the two-dimensional array through the subscript r * M + c with the subscript (r, c) element:

     
int *arr = new int[N * M];
    int *arr = new int[N * M];

    This method can ensure that the physical space of the two-dimensional array is continuous.

  • Storage through variables The first address of the array of arrays - the address of a pointer to a one-dimensional array. This variable is double pointer:

     
    int **arr = new int*[M];
    for (int i = 0; i < M; i ++)
        a[i] = new int[N];
    

int **arr = new int*[M]; for (int i = 0; i < M; i ++) a[i] = new int[N];

It should be noted that the two-dimensional array obtained in this way cannot guarantee that its space is continuous.

To release the memory obtained in this way, a reverse operation is required: if you want to release each one-dimensional array, then release the address that stores the first address of the one-dimensional array:

 
 
 
 

for (int i = 0; i < M; i ++) delete[] arr[i]; delete[] arr;

  • for (int i = 0; i < M; i ++)
        delete[] arr[i];
    delete[] arr;
    

  • The third method uses pointer to the array:

    int (*arr)[N] = new int[M][N];
    /* ... */
    delete[] arr;
    

  • int (*arr)[N] = new int[M][N]; /* ... */ delete[] arr;

    This method also obtains continuous memory, but compared with the first method, you can directly use the form of arr[n] to obtain the array's n + 1 The first address of the line, use the form arr[r][c] to access the element with the index (r, c).

    Since a pointer to an array is also a deterministic data type, except for the first dimension of the array, the lengths of other dimensions must be a constant that can be determined by the compiler.

The main difference between malloc and new

feature new / delete malloc / free
allocated memory location free storage area heap
Memory allocation failed throw an exceptionbac_alloc returnNULL
Allocate memory size The compiler calculates based on the type Explicitly specify the number of bytes
Processing arrays new[] Manually calculate the array size and then allocate memory
Expansion of allocated memory not support realloc
Insufficient memory when allocating You can specify a handler function or re-specify the allocator Cannot be handled by user code
Is it possible to overload Can Can't
Constructors and destructors transfer Not called

Guess you like

Origin blog.csdn.net/qq_72290695/article/details/134609729