动态内存开辟

简介: 动态内存开辟

动态内存开辟


1.动态内存开辟相关试题


题目1:

void GetMemory(char *p)
{
    p = (char *)malloc(100);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(str);
    strcpy(str, "hello world");
    printf(str);
}

解释:这里在Test函数中,只是将str指针本身传过去了,在Getmemory函数中,对形参p进行修改并不会影响到Test函数中str


变量的值。出了Germemory函数str的值还是NULL,此时srtcpy函数对str这个空指针进行操作就是不合法的操作,导致程序错误。


题目二:

char *GetMemory(void)
{
    char p[] = "hello world";
    return p;
}
void Test(void)
{
    char *str = NULL;
    str = GetMemory();
    printf(str);
}

解释:在Getmemory函数中开辟的空间是在栈区上开辟的,当Getmemory函数运行结束时,p所指向的内存空间就已经还给操作系统了,并且被赋值为了随机值。所以在Test函数中打印str指向的空间时,打印出的应该是一串乱码。


题目三:

void GetMemory(char **p, int num)
{
    *p = (char *)malloc(num);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(&str, 100);
    strcpy(str, "hello");
    printf(str);
}

解释:这段代码不细看是没有什么问题的,在Test函数中的printf函数执行结束之后,str仍然指向堆空间中的内存。在程序结束之前应该主动将其释放。


题目四:

void Test(void)
{
    char *str = (char *) malloc(100);
    strcpy(str, "hello");
    free(str);
    if(str != NULL)
    {
        strcpy(str, "world");
        printf(str);
    }
}

解释:在free释放了堆中开辟的空间时,应该及时的将free的参数设置为NULL。这里假如代码的第五行执行完毕之后,将str设置为了空指针,就不会出现后续的错误了。


2.c/c++程序中的内存开辟


内存图如图所示。


栈区向下增长,堆区向上增长。栈区和堆区之间是内存映射段。


5898958a74193c3f3660d68ed82108b7_5c4fbd29359c44d49a619e38283a1f48.png


c/c++程序内存分配的几个区域:


  1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。
  2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。
  3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
  4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码。


有了这些知识,就可以理解之前为什么加了static的局部变量可以全局使用了:


局部变量实际上是在内存中的栈区开辟空间的, 栈区上的变量的特点就是出了作用域之后,就被销毁。但是被static修饰的变量是存储在数据段的,会一直持续到程序结束才会被销毁,所以被static修饰的局部变量的生命周期变长了。


3.完结

动态内存开辟的全部内容就到这里啦,若有不足,欢迎评论区指正,下期见!


相关文章
|
6月前
|
编译器 C语言 C++
【C语言】realloc()函数详解(动态内存开辟函数)
【C语言】realloc()函数详解(动态内存开辟函数)
93 0
|
6月前
|
编译器 C++
C/C++动态内存开辟(详解)
C/C++动态内存开辟(详解)
|
存储 编译器 C语言
C语言进阶第六课-----------字符分类函数和内存的开辟 2
C语言进阶第六课-----------字符分类函数和内存的开辟
|
C语言
C语言进阶第六课-----------字符分类函数和内存的开辟 1
C语言进阶第六课-----------字符分类函数和内存的开辟
|
程序员 编译器 C语言
动态内存函数,内存开辟,柔性数组(超详细)
动态内存函数,内存开辟,柔性数组(超详细)
73 0
|
Unix 程序员 Linux
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
265 0
|
5月前
|
C语言
C语言学习记录——动态内存开辟常见的错误
C语言学习记录——动态内存开辟常见的错误
33 1
|
6月前
|
编译器 C++
内存对齐与内存开辟。结构体(struct),位段,枚举类型(enum),联合体(union)。
内存对齐与内存开辟。结构体(struct),位段,枚举类型(enum),联合体(union)
38 1
|
5月前
|
C语言
动态内存开辟(下)
动态内存开辟(下)
22 0
|
5月前
|
编译器 C语言
动态内存开辟(上)
动态内存开辟(上)
25 0