内存分配、野指针、指针、数组相关

内存分配方式有哪些?

C语言内存分配方式


1)        从静态数据区分配,该内存在程序编译的时候就已经分配好,直到程序运行结束。分为BSS、Data、Rodata段,BSS存放未初始化的全局变量,Rodata存放常量,data存放初始化的全局变量和静态变量。

2)        从堆上分配,动态内存分配,程序运行时用new,malloc分配的空间,声明周期由用户决定,free/delete。向上增长。

3)        从栈上分配,在执行函数时,函数内的局部变量的存储单元可以在栈上创建,函数运行结束后内存释放,这段内存执行效率高,容量有限。向下增长。

 

什么是内存泄漏?

内存泄漏:访问已经释放的内存;访问没有权限的内存。

常发性内存泄漏:发生内存泄漏的代码被多次执行到,每次执行都会造成一块内存泄漏;

偶发性内存泄漏:发生内存泄漏的代码只有在特定的环境下或操作过程下才发生;

一次性内存泄漏:发生内存泄漏的代码只执行一次,或者由于算法的取消,导致总有一块且只有一块内存泄漏。

隐藏性内存泄漏:在程序运行过程中不断地分配内存,到程序运行结束后才释放内存,严格来说没有发生内存泄漏,但长时间运行之后才结束就回造成所有内存耗尽。

 

什么是野指针?如何避免野指针?

什么是野指针:

1)        指针变量没有初始化;

2)        指针free后没有置为NULL;

3)        指针操作超越变量的作用范围。

如何避免?

1)        对指针进行初始化:将指针初始化为NULL;用malloc分配内存;用已有合法的可访问的内存地址初始化

2)        指针用完后释放,并置为NULL,用malloc分配内存的步骤:

a)        malloc分配内存(分配成功,返回内存首地址,失败返回NULL)

b)        判断内存是否分配成功(失败,exit(1),退出程序)

c)        清空内存数据(memset\bzero)

d)        使用内存

e)        释放内存

f)         置为NULL

 

什么时候将引用作为返回值

1)        将引用作为返回值,在内存中不产生被返回值的副本,提高程序的安全性和效率。

2)        不能返回局部变量的引用

3)        不能返回函数内部new分配的内存引用

4)        返回类成员的引用,最好是常引用。

5)        流操作符<<、>>返回引用

6)        不能返回引用的是+-*/,应该返回对象。

 

引用与指针的区别

1)        引用访问一个变量是直接访问,指针是简介访问;

2)        指针是存放变量地址的一个变量,在逻辑上是独立的,它可以改变,指向的地址也可以改变;引用只是一个别名,在逻辑上是不独立的,一旦初始化,它引用的对象在整个生命周期不能改变。

3)        引用只是一个别名,本身不单独分配内存空间,指针有自己的内存空间。

4)        引用在定义时就必须初始化,指针可以不初始化。

5)        引用经初始化后就不能引用其他变量,指针可以。

6)        sizeof求指针大小时是固定的值(32位系统下为4),而引用的值不固定,其大小是所引用对象的大小。

7)        引用不可以为空,指针可以。

8)        引用使用时不需要解引用,指针需要。

9)        指针和引用的自增运算意义不同。

10)    返回动态分配的对象或内存时,必须使用指针,使用引用可能造成内存泄漏。

 

数组与指针的区别

1)        数组和指针的定义与声明是不同的,定义是数组时,声明也应该是数组。

2)        数组可以在静态存储区或栈上被创建,数组名对应一块内存,其地址和容量在生命期内保持不变,只有数组内容可以改变;但是指针可以随时指向任意类型的内存块,可以改变,指针比数组灵活,但也比数组危险。

3)        当用下标操作符对数组和指针进行运算时,数组和指针是等价的,a[i]编译器会翻译成*(a+i).

4)        当数组名作为函数形参时,数组实际会当做指针来使用。

5)        修改内容不同,数组可以通过下标对数组内容进行修改,但一个指向常量字符串的指针,不能进行修改。

6)        内容复制与比较。不能对数组名直接进行复制和比较,要用strcpy、strcmp函数

7)        计算内存容量,对数组求sizeof可以获得数组的容量,但是对指针求sizeof只能得到固定的指针变量的字节数。

 

函数指针与指针函数的区别

1)        函数指针,其本质是一个指针变量,该指针指向一个函数,一般形式为:type (*指针变量名)(形参表);

2)        指针函数,其本质是一个函数,返回值为一个指向函数的指针变量,一般形式为:type *函数名(形参表);

 

数组指针与指针数组的区别

1)        数组指针,其本质是一个指针变量,指针指向一个数组,一般形式为:type (*指针变量名)[10];

2)        指针数组,其本质是一个数组,数组元素是指针,一般形式为:type *数组名[10];

 

指针常量与常量指针的区别

1)        指针常量是指指针指向不能改变(const在*右边)

2)        常量指针是指指针指向的变量是常量,其值不能通过指针来改变(const 在*左边)


函数模板与模板函数的区别

1)        函数模板是对一批模样相同的函数的说明描述,不是一个具体的函数,是抽象的。

2)        模板函数是将函数模板中的数据类型参数具体化的重载函数,是具体的。

 

类模板与模板类的区别

1)        类模板是代码类似的类的集合,是类的抽象

2)        模板类是具体化后的来模板,是具体的。

 

引入类模板的好处

1)        可以用来创建动态增长或减小的数据结构

2)        类型无关,具有很高的复用性

3)        在编译时而不是运行时检查数据类型,保证类型安全

4)        平台无关,可移植性强

5)        可用于基本数据类型


重载overload、覆盖overwrite、隐藏override的区别

1)        重载的条件:相同的范围(同一个类中);函数名相同;参数列表不同;virtual可有可无

2)        覆盖的条件:不同的范围(派生类、基类);函数名相同、参数列表相同;必须有virtual

3)        隐藏的条件:不同的范围(派生类、基类);函数名相同;参数列表可同可不同,相同时,virtual可有可无,区别于重载(范围是否相同),不同时,没有virtual(区别于覆盖)

4)        覆盖根据对象的类型选择方法体,重载根据参数列表选择方法体

 



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值