首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C语言进阶篇-01内存分配原理

C语言内存分配,主要重点讲解栈区和堆区 栈区 栈是一种先进后出内存结构,由编译器自动分配释放,存放函数参数值、返回值、局部变量等。...因此,函数返回,str 将被销毁,其内存地址也将被回收。 当我们在 test02() 函数调用 getString() 函数并将其返回值赋给指针 p ,p 指向是一个已经被销毁字符串。...这样指针被称为“悬挂指针”,使用它将导致未定义行为。...然后,我们将 temp 指向内存地址赋给了 pp,但 pp 是一个指向 test02() 函数中局部变量 p 指针,我们并没有改变 p 指向,而是改变了 pp 指向,因此 test02() 函数...在 test02() 函数,我们尝试打印 p 指针指向字符串,但由于 p 仍然是 NULL,因此打印结果也是不确定,有可能是一个空字符串,也有可能是其他未定义内容。

16420

内存之谜:C语言动态内存管理

作用是在堆上分配指定字节数未初始化内存,并返回指向这块内存指针。如果分配成功,将返回一个指针指针可以被转换为适当类型指针以访问内存区域。如果分配失败,将返回一个 NULL 指针。...size 参数是每个元素大小(以字节为单位) calloc 函数返回一个指向新分配内存指针内存大小为 num * size。如果分配成功,返回内存块所有位都被初始化为零。...} p 被增加之后,它不再指向原先由 malloc 分配内存起始地址,而是指向块内存下一个 int 位置。...但这里 p 是一个局部变量,它是主调函数 Test str 一个拷贝。因此, GetMemory 返回,分配内存地址并没有传递回 str。str 仍然是 NULL。...此时,str 仍然是一个非 NULL 悬垂指针。 尝试访问或操作悬垂指针指向内存将导致未定义行为,这可能包括数据损坏、程序崩溃、或者安全漏洞。

6710
您找到你想要的搜索结果了吗?
是的
没有找到

C++奇迹之旅:值和引用本质效率与性能比较

,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量一份临时拷贝,因此用值作为参数或者返回值类型,效率是非常低下,尤其是参数或者返回值类型非常大,效率就更低...问题分析: 如果函数返回,返回对象已经超出了函数作用域(即已经被销毁),那么不能返回对象引用,必须返回值。...在第一个示例: int& Add(int a, int b) { int c = a + b; return c; } 这里函数返回局部变量c引用,但c在函数返回后就已经被销毁了...main函数又调用了一次Add函数,这时第一次调用返回引用ret已经指向了一个不存在对象,所以输出结果也是未定义。...函数返回引用时必须确保返回对象在调用者作用域内仍然存在,否则就会产生未定义行为。这是C++函数返回引用需要特别注意地方。

9010

C语言重点突破(五) 动态内存管理

前言 动态内存管理是指在一个程序运行期间动态地分配、释放和管理内存空间过程。在应用程序程序需要使用变量或对象,需要在内存中分配一段空间,并在使用完毕后释放空间,以提高程序效率和性能。...如果参数 ptr 指向空间不是动态开辟,那free函数行为未定义。 如果参数 ptr 是NULL指针,则函数什么事都不做。 malloc和free都声明在 stdlib.h 头文件。...return 0; }  注意:每次free完后,指向动态内存空间指针必须置空,内存释放完后,指针变量仍然存在,此时会指向一个未知地址,不置空的话就成为了野指针,如果后续在进行调用的话是非常危险...这个函数调整原内存空间大小基础上,还会将原来内存数据移动到 新 空间 对一个空指针使用realloc函数,其效果相当于对指针使用melloc函数开辟空间。...但是,对于非动态开辟内存,如全局变量、静态变量局部变量等,我们不能使用free/delete等函数释放内存。 在C/C++,对于非动态开辟内存,内存分配和释放都是由编译器自动完成

7510

CC++面试题之语言基础篇(一)

C和C++都有结构概念,但是在C语言中结构只有成员变量没有成员方法,而在C++结构,它可以有自己成员变量以及成员方法。...new 返回指针,不需要进行类型转换;malloc 返回是void *(无类型指针)。...同时编译多个文件,所有未加static前缀全局变量和函数都具有全局可见性,故使用static在不同文件定义同名函数和同名变量,而不必担心命名冲突。...注意:数据成员中有指针,必须要用深拷贝 左值引用和右值引用区别和目的 左值是能够出现在表达式左边值如变量,右值是只能出现在等号右边值,如常量。 左值可以取地址,右值不可。...结构比较,怎么判断两个对象是否相等 需要逐个比较它们成员变量(字段) 继承关系子类能访问父类哪些成员变量以及成员函数 在继承关系,子类(派生类)通常可以访问父类(基类)以下成员变量和成员函数

14310

【C】动态内存函数——大全(基本,简洁,包教会,适合初学)

如果参数ptr指向空间不是动态开辟,那free函数行为未定义 如果参数ptr是NULL指针,则函数什么事都不做 使用场景: int num=10; int* p=NULL; free(p)...返回值一定要检查 返回类型是void*,所以malloc函数并不知道开辟空间类型,具体在使用时候使用者自己来决定 如果参数size为0,malloc行为未定义,取决于编译器 情景1:申请内存空间失败...——返回指针 情景2:动态内存底层原理 局部变量特点,进函数创建,出函数销毁 局部变量放在栈区 动态内存分配放在堆区,不会自动摧毁,直到程序退出才释放。...,如果成功再给p指针 情景2:realloc调整空间,分类讨论(内存空间足够与否) 内存空间足够,拓展方法:就直接原有内存之后直接追加空间,原来空间数据不发生变化,这样函数返回是原内存地址 内存空间不足...C99结构最后一个元素允许是未知大小数组 柔性数组两种写法: 有些编译器无法编译,可以改成: 1.柔性数组特点 结构柔性数组成员前面必须至少有一个其他成员 sizeof

10610

C语言动态内存分配函数malloc(),calloc(),realloc()用法对比分析

) malloc()函数会向堆申请一片连续可用内存空间 若申请成功则返回指向这片内存空间指针 ,若失败 ,则会返回NULL, 所以我们在用malloc()函数开辟动态内存之后, 一定要判断函数返回是否为...= NULL){ //....需要进行操作 } 2.free() void free(void* ptr)//ptr是开辟动态内存地址 在堆申请内存空间不会像在栈存储局部变量一样...如果ptr没有指向使用动态内存分配函数分配内存空间,则会导致未定义行为。 如果ptr是空指针,则该函数不执行任何操作。...若申请成功 ,,返回指向这片内存空间指针 ,若失败 ,则会返回NULL, 所以我们在用calloc()函数开辟动态内存之后, 一定要判断函数返回是否为NULL....若调整成功, 返回值为调整大小后内存起始位置(也就是指向调整后内存指针), 若失败(没有内存可以分配, 一般不会出现), 则返回NULL, 所以还是要对返回值判空。

1.2K10

C++面试题

3、内存块太小导致malloc和new返回指针怎么处理?...对于malloc来说,需要判断其是否返回指针,如果是则马上用return语句终止该函数或者exit终止程序; 对于new来说,默认抛出异常,所以可以使用try...catch...代码块方式: try...,从而造成两次释放相同内存做法;比如,类包含指针成员变量,在未定义拷贝构造函数或未重载赋值运算符情况下,编译器会调用默认拷贝构造函数或赋值运算符,以逐个成员拷贝方式来复制指针成员变量,使得两个对象包含指向同一内存空间指针...,那么在释放第一个对象,析构函数释放指针指向内存空间,在释放第二个对象,析构函数就会释放同一内存空间,这样行为是错误; 没有将基类析构函数定义为虚函数。...在栈上分配:在执行函数局部变量内存都可以在栈上分配,函数结束时会自动释放;栈内存分配运算内置于处理器指令集中,效率很高,但分配内存容量有限; 从堆上分配:由new分配/delete释放内存块

97430

C语言动态内存分配函数

在堆申请内存空间不会像在栈存储局部变量一样 ,函数调用完会自动释放内存 , 需要我们手动释放 ,就需要free()函数来完成....2).若申请成功 ,,返回指向这片内存空间指针 ,若失败 ,则会返回NULL, 所以我们在用malloc()函数开辟动态内存之后, 一定要判断函数返回是否为NULL. 3).返回类型为void.... 1).如果ptr没有指向使用动态内存分配函数分配内存空间,则会导致未定义行为。...返回值为调整大小后内存起始位置(也就是指向调整后内存指针), 若失败(没有内存可以分配, 一般不会出现), 则返回NULL, 所以还是要对返回值判空 4).如果ptr是空指针, 则和malloc...第二种情况, 若申请新内存空间成功, 会将ptr所指向内存内容拷贝到新内存空间中, ptr所指向内存会被释放, 返回新得内存地址, 若不成功 ,ptr 所指内存不会被释放, 函数返回

1.6K30

【C语言】深入解开指针(二)

指针指向空间释放 在C语言中,一个指针指向一个函数中分配内存空间,如果在该函数返回之前释放了内存空间,那么这个指针就成为了一个野指针。...这是因为在函数返回后,内存空间已经被释放,指针再次访问这个空间就会导致未定义行为。 因此,当你使用指针指向调用函数空间,你应该确保在函数返回之前不要释放这个内存空间。...建议:如果你需要在函数外部访问这个空间,你应该将其复制到一个新内存空间中,并在函数返回之前释放原始内存空间。 函数test()返回了一个指向局部变量指针。...函数test()执行完毕后,它局部变量a内存空间会被释放。因此,返回指针指向内存空间已经无效了。在这种情况下,pa是一个野指针,因为它指向内存空间已经不再有效。...指针变量不再使⽤,及时置NULL,指针使⽤之前检查有效性 避免返回局部变量地址 四、 assert断⾔ assert.h 头⽂件定义了宏 assert() ,⽤于在运⾏确保程序符合指定条件,如果不符合

7810

动态内存管理

动态内存函数介绍 malloc void* malloc (size_t size); 向内存申请一块连续可用空间,并返回指向这块空间指针。 如果开辟成功,则返回一个指向开辟好空间指针。...返回类型是 void* ,所以malloc函数并不知道开辟空间类型,具体在使用时候使用者自己来决定(强制转换)。 如果参数 size 为0,malloc行为是标准是未定义,取决于编译器。...free void free (void* ptr) free函数用来释放动态开辟内存。 如果参数 ptr 指向空间不是动态开辟,那free函数行为未定义。...栈区(stack):在执行函数,函数内局部变量存储单元都可以在栈上创建,函数执行结束这些存储单元自动被释放。栈内存分配运算内置于处理器指令集中,效率很高,但是分配内存容量有限。...栈区主要存放运行函数而分配局部变量、函数参数、返回数据、返回地址等。 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束可能由OS回收 。分配方式类似于链表。

60930

独特视角解读JVM内存模型

好处: 有利于堆碎片整理,移动对象池中对象,句柄部分只需要更改一下指针指向对象新地址即可 缺点: 访问对象实例数据都要经过两次指针传递 另一种设计方式是使对象指针直接指向一组数据,组数据包括对象实例数据以及指向方法区类数据指针...实例方法数据"指针,方法表指向实例方法数据包括以下信息: 此方法操作数栈和局部变量大小 此方法字节码 异常表 这些信息足够虚拟机去调用一个方法,方法表包含有方法指针指针指向当前类或者其超类什么方法数据...,在执行这个方法,使用帧来存储参数,局部变量,中间运算结果等数据。...虚拟机调用某个方法,它从对应类型信息得到此方法局部变量区和操作数栈大小,并据此分配栈帧内存,然后压入Java栈。...两个局部变量作用域不重叠,可以使用局部变量数组中一个索引指代两个局部变量

35820

JavaScript之再学习

引用计数:引用计数含义是跟踪记录每个值被引用次数。声明了一个变量并将一个引用类型值赋给变量,则这个值引用次数就是1。如果同一个值又被赋给另一个变量,则引用次数加1。...,而通过构造函数初始化原型(仅第一个对象实例化时初始化原型),这个可以通过判断方法是否有效而选择是否需要初始化原型。...bar ,创建了第一个帧 ,帧包含了 bar 参数和局部变量。... bar 调用 foo ,第二个帧就被创建,并被压到第一个帧之上,帧包含了 foo 参数和局部变量 foo 返回,最上层帧就被弹出栈(剩下 bar 函数调用帧 )。... bar 返回时候,栈就空了。 堆 对象被分配在一个堆,即用以表示一个大部分非结构内存区域。 队列 一个 JavaScript 运行时包含了一个待处理消息队列。

31810

C语言进阶-动态内存管理柔性数组

,并返回指向空间指针 如果开辟成功,则返回一个指向开辟好空间指针,并且所开辟空间内容都为随机值 如果开辟失败,则返回一个NULL指针,因此malloc返回值一定要做检查 返回类型是 void...free函数 作用: 专门是用来对动态开辟内存进行释放和回收 定义: void free (void* ptr); 注意: 如果参数 ptr 指向空间不是动态开辟,那free函数行为未定义...: 栈区(stack):在执行函数,函数内局部变量存储单元都可以在栈上创建,函数执行结束这些存储单元自动被释放。...栈区主要存放运行函数而分配局部变量、函数参数、返回数据、 返回地址等 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束可能由OS回收 (分配方式类似于链表) 数据段(静态区)(static...)存放全局变量、静态数据(程序结束后由系统释放) 代码段:存放函数体(类成员函数和全局函数)二进制代码 柔性数组 概念: C99 结构最后一个元素允许是未知大小数组,这就叫做『柔性数组

59420

动态内存分配(malloc和free​、calloc和realloc​)

栈区主要存放运行函数而分配局部变量、函数参数、返回数据、返回地址等。​ 2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束可能由OS回收 。分配方式类似于链表。 3....如果参数 ptr 指向空间不是动态开辟,那free函数行为未定义。 如果参数 ptr 是NULL指针,则函数什么事都不做。...20个整型变量空间 // 注意,这里使用了临时指针ptr来接收realloc返回值, //以防realloc失败返回NULL导致原指针丢失 if (ptr !...,此时 p 和 str 是各自独立两个指针变量,但它们都是空指针,此时在函数内部让 p 重新指向新开辟出来空间,此时 p 就不是空指针了,GetMemory 函数结束时候 p 会被释放掉,接下来执行...其中最明显是试图返回一个局部变量地址。在C语言中,函数执行完毕后,其栈上局部变量会被销毁,因此返回局部变量地址是不安全

17110

Java虚拟机

启动一个Java程序时,一个虚拟机实例也就诞生了,程序关闭退出,这个虚拟机实例也就随之消亡。...程序中所有的非守护线程都终止,虚拟机实例将自动退出。 3、Java虚拟机体系结构 ? 一个虚拟机实例行为是分别按照子系统、内存区、数据类型以及指令这几个术语来描述。 3.1、数据类型 ?...只要有一个对象引用,虚拟机就必须能快速定位对象实例数据,另外,它必须能通过对象引用访问相应类数据,因此对象通常有一个指向方法区指针。...方法表指向实例方法数据包括以下信息: 此方法操作数栈和局部变量大小 此方法字节码 异常表 这些信息足够虚拟机去调用一个方法了,方法表包含有方法指针——指向类活或超类声明方法数据 ?...虚拟机调用一个方法,它从对应类类型信息得到此方法局部变量区和操作数栈大小,并据此分配栈帧内存,然后压入Java栈

1.2K100

C语言_动态内存管理

如果开辟成功,则返回一个指向开辟好空间指针。 如果开辟失败,则返回一个NULL指针,因此malloc返回值一定要做检查。...返回类型是void*,所以malloc函数并不知道开辟空间类型,具体在使用时候使用者自己来决定。 如果参数size为0,malloc行为是标准是未定义,取决于编译器。...malloc 申请内存空间,程序退出,还给操作系统。 程序不退出,动态申请内存,不会主动释放。 需要使用 free 函数来释放。...程序结束(退出) 四.C/C++中程序内存区域划分 栈区(stack): 在执行函数,函数内局部变量存储单元都可以在栈上创建,函数执行结束这些存储单元自动被释放。...五.柔性数组 柔性数组前面至少得有一个其它成员 5.1 柔性数组特点 结构柔性数组成员前面必须至少一个其他成员。 sizeof 返回这种结构大小不包括柔性数组内存。

20120

谈谈如何利用 valgrind 排查内存错误

即程序中使用了未初始化变量或者从上层未初始化变量逐层传递下来未定义值。 一般来讲,这类错误都是变量定义后未初始化导致。...进程在运行或者进程结束,如果一块动态分配内存没有被释放,并且程序已经找不到能够正常访问这块内存指针,则会报这个错误。...也就是说指针已丢失,但是内存未释放,这是真正需要被关注内存泄漏,需要尽快修复。 indirectly lost,指针间接丢失。 使用了含有指针成员类或结构可能会报这个错误。...进程结束,如果一块动态分配内存没有被释放,且通过程序内指针均无法访问这块内存起始地址,但是可以访问这块内存部分数据,那么指向内存块指针可能丢失。...我们 new 一个数组并返回局部变量 data,随后声明静态指针 p 并指向数组第二个元素地址,test04 测试结束后直到 main 函数返回前,静态指针 p 仍然可获得,但是 p 已经不再指向数组起始地址

5.7K41

练习使用动态内存相关4个函数:malloc、calloc、realloc、free

如果开辟成功,返回一个开辟成功指针。 如果失败,则返回NULL。因此,在malloc使用之前必须检查是否为空指针返回类型为void*,因此,返回类型由自己来决定。...同时,size为0时候,malloc行为是标准未定义,这取决于编译器。 free free函数是专门用来做动态内存释放和回收。...void free (void* ptr); free函数用来做动态内存释放,如果ptr指向空间不是动态内存,那么free行为就是标准未定义。...malloc出空间地址放到p指针,p销毁,还给操作系统。回来时候,str依然为空指针。...结构柔性数组成员前⾯必须⾄少⼀个其他成员。 sizeof返回这种结构⼤⼩不包括柔性数组内存。

9110
领券