Dynamic Memory Request

1. Overview of dynamic memory allocation

The length of the array is predefined and fixed throughout the program, but in actual programming, it often happens that the required memory space depends on the actual input data and cannot be determined in advance.
In order to solve the above problems, C language provides some memory management functions, these memory management functions can dynamically allocate memory space as needed, and can also recycle the unused space for reuse.
Dynamic memory allocation is to open up space in the heap area.

Two, static allocation, dynamic allocation

static allocation

  1. In the process of program compilation or operation, the allocation method of allocating memory space according to the predetermined size. int a [10];
  2. The size of the required space must be known in advance.
  3. Allocated in the stack area or global variable area, generally in the form of an array.
  4. Allocate according to plan.

dynamic allocation

  1. During the running of the program, the required space can be allocated freely according to the required size.
  2. Allocate as needed.
  3. Allocated in the heap area, generally using a specific function for allocation.

3. Dynamic allocation function

malloc

#include <stdlib.h>
void *malloc(unsigned int size);
// 功能:在堆区开辟指定长度的空间,并且空间是连续的
// 参数:
// size:要开辟的空间的大小
// 返回值:
// 成功:开辟好的空间的首地址
// 失败:NULL

Notice:

  1. After calling malloc, be sure to judge whether the application for memory is successful.
  2. If the memory requested by malloc is multiple times, the memory requested for the first and second time is not necessarily continuous
  3. Using malloc to open up space needs to save the first address of the opened space, but because it is not sure what the space is used for, the return value type itself is void *, so it is cast according to the type of the receiver when calling the function.
#include <studio.h>
#include <stdlib.h>

char *fun()
{
    
    
    //char ch[100] = "hello world";

    /* 静态全局区的空间只要开辟好,除非程序结束,否则不会释放,
       所以如果是临时使用,不建议使用静态全局区的空间*/
    // static char ch[100] = "hello world";

    /* 堆区开辟空间,手动申请手动释放,更加灵活
       使用malloc函数的时候一般要进行强转 */
    char *str = (char *)malloc(100 * sizeof(char));
    str[0] = 'h';
    str[1] = 'e';
    str[2] = 'l';
    str[3] = 'l';
    str[4] = 'o';
    str[5] = '\0';

    return str;
} 

int main(int argc, char *argv[])
{
    
    
    char *p;
    p = fun();
    printf("p = %s\n", p);

    return 0;
}

Results of the:

p = hello

free

#include <stdlib.h>

void free(void *ptr)
/* 功能:释放堆区的空间 */
/* 参数:
    ptr:开辟后使用完毕的堆区的空间的首地址 */
/* 返回值:无 */ 

Notice:

  1. freeThe function can only release the space in the heap area, and the space in other areas cannot be used free.
  2. freeTo release space, you must release the space corresponding to the return value of or malloc, and it cannot be said that only part of it is released.callocrealloc
  3. free(p); Note that freelater, because no value is passigned, it pstill points to the originally dynamically allocated memory. But the memory can no longer be used, pand it has become a wild pointer, so generally in order to place the wild pointer, it will be assigned freeafter the meeting is completed .pNULL
  4. A piece of dynamically allocated memory can only be allocated freeonce, not multiple times free.
/* 使用free函数释放空间 */
free(p);
/* 防止野指针 */
p = NULL; 

calloc

#include <stdlib.h>

void * calloc(size_t nmemb, size_t size);
/* 功能:在堆区申请指定大小的空间 */
/* 参数:
    nmemb:要申请的空间的块数
    size:每块的字节数 */
/* 返回值:
    成功:申请空间的首地址
    失败:NULL */

Note:
Both malloc and calloc functions are used to apply for memory.
the difference:

  1. function name is different
  2. The number of parameters is different
  3. The memory requested by malloc, the content stored in the memory is random and uncertain,
    while the content in the memory requested by the calloc function is 0

For example:

char *p=(char *)calloc(3,100);

Apply for 3 blocks in the heap, each with a size of 100 bytes, that is, a continuous area of ​​300 bytes.

realloc

#include <stdlib.h>

void* realloc(void *s, unsigned int newsize);
/* 功能:在原本申请好的堆区空间的基础上重新申请内存,
   新的空间大小为函数的第二个参数;
   如果原本申请好的空间的后面不足以增加指定的大小,
   系统会重新找一个足够大的位置开辟指定的空间,
   然后将原本空间中的数据拷贝过来,然后释放原本的空间。
   如果newsize比原先的内存小,则会释放原先内存的后面的存储空间,
   只留前面的newsize个字节 */
/* 参数:
    s:原本开辟好的空间的首地址;
    newsize:重新开辟的空间的大小 */
/* 返回值:
    新的空间的首地址 */ 

Add space:

char *p;
p = (char *)malloc(100);
// 想在100个字节后面追加50个字节
p = (char *)realloc(p,150);
// p指向的内存的新的大小为150个字节 

increase space
Reduce space:

char *p;
p = (char *)malloc(100);
// 想重新申请内存,新的大小为50个字节
p = (char *)realloc(p,50);
/* p指向的内存的新的大小为50个字节,
   100个字节的后50个字节的存储空间就被释放了 */ 

Note: malloc,calloc,relloc The dynamically allocated memory is only freereleased when the program ends.

4. Memory leak

The concept of memory leak: the first address of the requested memory is lost, cannot be found, can no longer be used, and cannot be released, and this piece of memory is leaked.
eg1:

int main()
{
    
    
    char *p;
    p = (char *)malloc(100);
    //接下来,可以用p指向的内存了
    p = "hello world";
    /* p指向别的地方了,保存字符串常量的首地址
       从此以后,再也找不到你申请的100个字节了。
       则动态申请的100个字节就被泄露了 */
    return 0;
}

eg2:

void fun()
{
    
    
    char *p;
    p = (char *)malloc(100);
    //接下来,可以用p指向的内存了
    ...
}

int main()
{
    
    
    //每调用一次fun泄露100个字节
    fun();
    fun();
    return 0;
}

Solution 1:

void fun()
{
    
    
    char *p;
    p = (char *)malloc(100);
    //接下来,可以用p指向的内存了
    ...
    free(p);
}

int main()
{
    
    
    fun();
    fun();
    return 0;
}

Solution 2:

char * fun()
{
    
    
    char *p;
    p = (char *)malloc(100);
    //接下来,可以用p指向的内存了
    ...
    return p;
}

int main()
{
    
    
    char *q;
    q = fun();
    //可以通过q使用 ,动态申请的100个字节的内存了
    //记得释放
    free(q);
    //防止野指针
    q = NULL;
    return 0;
}

Summary: Do not lose the first address of the requested memory, and release the memory when not in use.

Guess you like

Origin blog.csdn.net/shuting7/article/details/130100558