,但不是同一个变量,在函数中改变这个变量的指向不影响实参,而引用却可以。...引用一旦初始化之后就不可以再改变(变量可以被引用为多次,但引用只能作为一个变量引用);指针变量可以重新指向别的变量。 不存在指向空值的引用,必须有具体实体;但是存在指向空值的指针。...静态变量在函数内定义,始终存在,且只进行一次初始化,具有记忆性,其作用范围与局部变量相同,函数退出后仍然存在,但不能使用。...数组名不是真正意义上的指针,可以理解为常指针,所以数组名没有自增、自减等操作。...在任何同一时刻,union值存放了一个被先选中的成员,而结构体struct的所有成员都存在。 27、什么是野指针和悬空指针?
在执行函数时, 函数内局部变量的存储单元都可以在栈上创建 ,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。 (3)从堆上分配 , 亦称动态内存分配 。...]表示指针数组,强调数组概念,是一个数组变量,数组大小为10,数组内每个元素都是指向int类型的指针变量。...- 指针free或delete之后没有及时置空 => 释放操作后立即置空。 ##### 指针和数组的区别 数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。...用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。...,每次用到这个变量的值的时候都要去重新读取这个变量的值,而不是读寄存器内的备份。
/just-a-try: 学习c语言的过程、真 (github.com) 今天来介绍动态内存管理 的相关内容: 一.为什么存在动态内存分配 我们熟悉的内存开辟方法: int a = 20;//在栈空间上开辟四个字节的空间...数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配 但是,有时候我们需 要的空间大小在程序运行的时候才能知道 , 那数组的编译时开辟空间的方式就不能满足了。...如果成功,会返回指向重新分配后的内存空间的指针;如果失败,会返回NULL,并且原来的内存空间仍然有效 扩展空间情况也有两种: 当原有空间之后有足够大的空间:要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化...} 在函数结束后,函数内动态分配的内存空间不会自动销毁。...这是因为动态分配的内存空间是在堆上分配的,而不是在函数的栈帧上。栈帧上的局部变量在函数结束时会自动销毁,但堆上分配的内存空间需要手动释放 。
为什么要给确认报文中的ack值加1,为什么不是2,3,4?...函数体static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值 在模板内的static全局变量可以被函数内所有函数访问,但不能模板外其他函数访问...引用时别名;指针是地址 程序为指针变量分配内存区域,而不为引用分配内存区域。 指针使用时要在前加 * ,引用可以直接使用。 引用在定义时就被初始化,之后无法改变;指针可以发生改变。...例如就++操作而言,对引用的操作直接反应到所指向的对象,而不是改变指向;而对指针的操作,会使指针指向下一个对象,而不是改变所指对象的内容。...全局变量保存在内存的全局存储区,占用静态的存储单元; 局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。 什么是平衡二叉树?
✨作者:@平凡的人1 ✨专栏:《C语言从0到1》 ✨一句话:凡是过往,皆为序章 ✨说明: 过去无可挽回, 未来可以改变 ---- 文章目录 为什么存在动态内存分配❓ 动态内存函数 malloc...和free calloc realloc 动态内存错误 经典笔试题 题目一: 题目二: 题目三: 题目四: C/C++程序的内存开辟 柔性数组 柔性数组的特点 柔性数组的使用 柔性数组的优势 总结 为什么存在动态内存分配...数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。 但是对于空间的需求,不仅仅是上述的情况。...栈内存分配运算内置于处理器的指令集中,效率很高,但是 分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返 回地址等。...总结 回顾一下,本篇博客我们主要介绍了C语言动态内存的相关知识,从为什么会存在动态内存分配开始,逐渐深入,认识了动态内存函数以及相关的使用,以及说明了一些常见的动态内存错误。
区别:所有函数都能访问全局变量,静态变量作用域则只局限于定义它的函数内部 自动内存 在函数内声明,函数调用时创建(分配在栈中),作用域局限于该函数内部,函数执行完则释放。...动态内存 内存分配在堆上,用完需手动释放,使用指针来引用分配的内存,作用域局限于引用内存的指针 为什么需要在堆上面分配动态内存?...,当原内存空间之后还有足够的内存可分配时,那么就会紧随原内存空间之后扩展空间,这样一来,realloc返回的void指针与指向原内存空间的指针相同;如果原内存空间之后没有足够的内存可扩展了,那么就在堆内存中其他的拥有足够空间的地方重新分配空间...可以看到,该函数之所以如此复杂,其目的就是为了保证申请的空间都是一片连续的内存空间,而不是碎片化的内存。...我们知道数组变量实际上也是一个指针,指向数组的起始地址,结构体指针也是指向第一个成员变量的起始地址,而函数指针亦是指向函数的起始地址。 所谓函数指针,就是一个保存了函数的起始地址的指针变量。
2 内存分配方式 内存分配方式有三种: (1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。 (2)在栈上创建。...在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。...(2)函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。...由于addr函数中的变量k在函数返回后就已经不存在了,但是在全局变量p中却保存了它的地址。...在下一个函数port中,试图通过全局指针p访问一个不存在的变量,而这个指针实际指向的却是另一个临时变量i,这就导致了死循环的发生。
参数:指向先前使用或分配的内存块的指针 值得注意的是: • 如果参数 ptr 指向的空间不是动态开辟的,那 free 函数的行为是未定义的 • 如果参数 ptr 是 NULL 指针,则函数什么事都不做...调整之后新大小 • 返回值为调整之后的内存起始位置 • 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间 • realloc 在调整内存空间的是存在两种情况: 情况1:原有空间之后有足够大的空间...赋给 ptr,所以 ptr 仍然指向原来的内存块(前提是原来的内存块还未被 realloc 释放,在这种情况下,原来的内存块未被释放是因为重新分配失败后没有进行释放原始内存块的操作),这样就可以避免丢失原始数据以及出现空指针错误...• 包含柔性数组成员的结构用 malloc () 函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小 3.2 柔性数组的使用 typedef struct st_type...,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放,栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限,栈区主要存放运行函数而分配的局部变量、函数参数、
目录 前言 为什么存在动态内存分配 动态内存函数的介绍 malloc和free函数 malloc函数: free函数 calloc函数 realloc函数 常见的动态内存错误 几个经典的笔试题 C/C+...+程序的内存开辟 柔性数组 柔性数组的特点 柔性数组的使用和优势 ---- 前言 ---- 本文章主要讲解: 动态内存管理的使用即注意事项 有关于动态内存管理的寄到笔试题讲解 柔性数组的使用 为什么存在动态内存分配...数组申明必须指定数组的长度,它所需要的内存在编译时分配) 但有时候我们需要的空间大小在程序运行的时候才能知道, 那数组的编译时开辟空间的方式就不能满足了,由此动态内存开辟就来了 动态内存函数的介绍...(此时不是内存泄漏) 而如果它在程序中没有被free就被指向另一块地址了(或者该被被销毁),那么就会导致这块地址在这个进程中永远无法被找到(即内存泄露:无用的内存越来越大,操作系统得一直给这个进程分配内存...栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、 返回地址等 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 (分配方式类似于链表) 数据段(静态区)(static
7 ,这里函数参数 str[] 已不再是数组类型,而是蜕变成指针,我们调用函数 GetStrLength() 时,程序会在栈上分配一个大小为 7 的数组吗?...向函数形参传递数组,数组将会退化为指针,失去原来数组的特性。 4 结构体类型的 sizeof 对于 struct 数据结构由 CPU 的对齐问题导致 struct 的大小变得比较复杂。...因为编译器为保证此空 struct 存在,专门分配一个字节。 如果存在结构体嵌套,无论内层还是外层均需要采用内存对齐。 5 类的 sizeof 不含继承和 static 成员变量的类。...而每次声明了类 A 的一个对象的时候,为该对象在堆上,根据对象的大小分配内存。...并且 sizeof 计算的是数据类型占内存的大小,而strlen 计算的是字符串实际的长度。 数组做 sizeof 的参数不退化,传递给 strlen 就退化为指针了。
itVect 之后的迭代器,迭代器相当于一个智能指针,之后迭代器将失效。...为什么是 1.5 倍 vector 通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,再插入新增的元素 初始时刻 vector...、引用和指针都失效 函数指针 函数指针指向的是特殊的数据类型,函数的类型是由其返回的数据类型和其参数列表共同决定的,而函数的名称则不是其类型的一部分 函数指针声明 int (*pf)(const...而 delete 会直接释放 p 指向的内存,这个内存根本没有被系统记录,所以会崩溃 需要在 new [] 一个对象数组时,需要保存数组的维度,C++ 的做法是在分配数组空间时多分配了 4 个字节的大小...由于静态全局变量的作用域限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。
运行结果为4,97;并不是4,0 说明:sizeof 不是标准意义上的一元操作符,不支持链式表达式,sizeof 作用域范围内的语句不会编译成机器码,如 sizeof(num++) 中的 ++ 不执行。...7 ,这里函数参数 str[] 已不再是数组类型,而是蜕变成指针,我们调用函数 GetStrLength() 时,程序会在栈上分配一个大小为 7 的数组吗?...向函数形参传递数组,数组将会退化为指针,失去原来数组的特性。 4 结构体类型的 sizeof 对于 struct 数据结构由 CPU 的对齐问题导致 struct 的大小变得比较复杂。...因为编译器为保证此空 struct 存在,专门分配一个字节。 如果存在结构体嵌套,无论内层还是外层均需要采用内存对齐。 5 类的 sizeof 不含继承和 static 成员变量的类。...而每次声明了类 A 的一个对象的时候,为该对象在堆上,根据对象的大小分配内存。
esp 作为栈顶指针,在函数返回后,也会被收回。虽然栈帧在函数返回后被回收,但是其中的数据并没有被回收,因此之前的数据仍然是存在的。...变量的地址是 0x0103fd6c,而 i 的值是0x0132a670,这值是一个地址,也就是由 new 分配的堆地址,看一下 0x0132a670 这个地址中的值,如下图: ?...这部分内存如果不是人为去写,一般数据不会被修改或覆盖。 前面说的是数组在堆中的情况,如果是在栈中的话,那么数组 i 的值都在栈中,即7、9、5 也在栈中。 简单说一下。...仍然在 func 的 return 处下断点,运行到这里,观察: ? 此时在 func 函数内,继续单步返回到 main 函数内: ?...观察,现在 ESP 和 EBP 已经恢复到 main 函数的栈帧内,而且代码也运行到了 main 的 for 内。 但是内存的栈中,func 函数内的 i 数组仍然存在。
字符串函数使用不当:使用如strcpy、strcat等不安全的字符串函数,而不是strncpy、strncat等安全的函数,容易导致越界。...释放后使用:释放了动态分配的内存后,仍然尝试访问该内存区域,会导致越界访问。...函数调用和参数传递 函数参数错误:传递给函数的参数如果超出预期范围,可能会导致函数内部的越界访问。例如,传递给函数的数组指针和数组大小参数不匹配。...,而不是strcpy、strcat等可能导致越界的函数。...free(ptr); ptr = NULL; 字符串操作 使用安全的字符串函数:使用如strncpy、strncat等安全的字符串操作函数,而不是strcpy、strcat等可能导致越界的函数。
,函数内的形参ptr // 获取外部实参的值之后,二者本身没有关系,但是由于是指针变量,二者之间又存在一丝关系,那就是函数内形参与函数外实参指向 // 同一块内存。...又由于函数外实参内存是动态分配的,因此函数内的形参可以使用free()函数进行内存释放,但一般不推荐这么做,因为函数内释放内存, // 会影响函数外实参的使用,可能使之成为野指针,那为什么这里可以用...int h等(实际经过测试,在gcc编译器下,能访问但是值被重新初始化为0), // 因为函数内形参和函数外实参共享一块堆内存,而这些非指针变量都是存在这块堆内存上的,内存一释放,就无法访问了;...但这些图片不是一个线程读完的,而是分配到多个线程并行读入, // 因此本函数中的n实际不是总的n,而是分配到该线程上的n,比如总共要读入128张图片,共开启8个线程读数据,那么本函数中的n为16...,而不是总数128 d.X.rows = n; //d.X为一个matrix类型数据,其中d.X.vals是其具体数据,是指针的指针(即为二维数组),此处先为第一维动态分配内存 d.X.vals
为什么存在内存分配 2. 动态内存函数的介绍 2.1 malloc和free 2.2 calloc 2.3 realloc 3....2.数组在申明的时候,必须指定数组长度,它所需要的内存在编译时分配。 但是对于空间的需求,不仅仅是上述的情况。...如果参数ptr指向的空间不是动态开辟的,那free函数的行为是未定义的。 如果参数ptr是NULL指针,那么函数什么事都不做。...5.C/C++程序的内存开辟 C/C++程序内存分配的几个区域: 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结 束时这些存储单元自动被释放。...栈内存分配运算内置于处理器的指令集中,效率很高,但是 分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返 回地址等。
3.局部变量 从栈上分配,其作用域只是在局部函数内,在定义该变量的函数内,只要出了该函数,该局部变量就不再起作用,也即该变量的生命周期和该函数同在。...4.局部静态变量 从静态存储区域分配,其在第一次初始化后就一直存在直到程序结束。该变量的特点是其作用域只在定义它的函数内可见,出了该函数就不可见了。...看到上面的第二张图,有的人可能会有疑问,为什么 short 不是紧挨着 char 呢?其实这个原因在上面已经给出了答案——自然对齐。为此,我们可以创建结构体验证自然对齐的规则。...不管基类型是什么类型的指针变量,他仍然是指针变量,所以仍然占用 8 字节。...free(),局部变量存在栈区,malloc()在堆区; 局部变量在函数执行完毕之后回收栈空间; 调用时传递进去的参数是str的一份备份。
数组实际占用的内存,只有这3个成员变量的内存(最少是16字节,一个指针+两个int,不同Allocator实际占用内存不同,最少的是一个指针),而实际元素的内存是由Allocator分配,具体大小就是ArrayMax...数组内部的内存扩容方式和STL的vector是差不多的,当容量满了之后,会额外分配一个更大的内存,将整个数组的数据拷到新内存上,之后再释放旧的内存(InlineAllocator不会释放Inline部分...其中指针加数量和TArrayView本质是一样的,都是从指针开始拷贝连续的内存到数组内。...个人更推荐使用TArrayView,因为TArrayView让指针和数量保存在同一个变量内,从语义上来说更合理,而且只要是连续的内存TArrayView都支持包装,包括默认静态数组,TStaticArray...,而传入的数组直接恢复到无分配的默认状态,因此使用移动构造函数可以让数组作为函数的参数和返回值,以及lambda时需要传入数组性能更好。
1.2 内存溢出原因 栈溢出:越界访问造成,例如局部变量数组越界访问或者函数内局部变量使用过多,超出了操作系统为该进程分配的栈的大小,还有递归函数层次过多超过了栈大小。...在编译的时候内联函数可以直接被嵌入到目标代码中,而宏只是一个简单的文本替换,内联函数可以完成诸如类型检测、语句是否正确等编译功能,宏就不具备这样的功能。inline函数是函数,宏不是函数。 ...因为不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,所以比指针安全。由于const 指针仍然存在空指针,并且有可能产生野指针,所以还是不安全。...程序会给指针变量分配内存区域,而引用不需要分配内存区域。 返回引用时,在内存中不产生被返回值的副本。...空指针:空指针表示“未分配” 或者“尚未指向任何地方” 的指针。 区别:空指针可以确保不指向任何对象或函数; 而未野指针或初始化指针则可能指向任何地方。
领取专属 10元无门槛券
手把手带您无忧上云