苏宁面试

1、vector和list区别

答:vector和数组类似,拥有一段连续的内存空间,并且其实地址不变。因此能高效的进行随机存取,时间复杂度为o(1);但因为内存空间是连续的,所以在进行插入和删除操作时候,会造成内存块的拷贝,时间复杂度为o(n);另外,当数组中的空间内存不够时候,会重新申请一块内存空间并进行内存拷贝。

list数据结构:list是双向链表实现的,因此内存空间是不连续的。只能通过指针访问数据,所以list的随机存取非常没有效率,时间复杂度为o(n);但由于链表的特点,能高效地进行插入和删除。

vector拥有一段连续的内存空间,能很好的支持随机存取,因此vector<int>::iterator支持“+”,“+=”,“<"等操作符。

list的内存空间可以是不连续的 ,它不支持随机访问,因此list<int>::iterator不支持上述的操作符。list<int>::iterator和list<int>::iterator都重载了“++”运算符。

总之,如果需要能高效的随机存取,而不在乎插入和删除的效率,使用vector;如果需要大量的插入和删除,而不关心随机存取,则应该使用list。

2、map容器实现原理

答:map容器的数据结构是采用红黑树进行管理,插入的元素健位不可以重复,所使用的节点元素的比较函数,只对元素的健值进行比较,元素的各项数据可通过健值检索出来。map容器是一种关联容器。

图中所示是map容器的一个元素是由健值和映照数据组成,可通过pair封装成一个结构对象。map容器所要的就是将这个pair对象插入到红黑树中,完成一个元素的添加。同时,也需要提供一个仅仅使用健值进行比较的函数对象,将它们传递给红黑树。由此,就可利用红黑树的操作,将map元素数据插入到二叉树中的正确位置,也可以根据健值进行元素的删除和检索。

3、c++中内存泄露的几种情况

答:1、在类中的构造函数和析构函数中没有匹配的调用new和delete函数:这两种情况下会出现这种内存泄露:一是在堆里创建了对象占用了内存,但是没有显示的释放对象占用的内存;二是在类中的构造函数中动态的分配了内存,但是析构函数中没有释放内存或者没有正确的释放内存。

2、没有正确地清除嵌套的对象指针

3、在释放对象数组时候delete中没有使用方括号

方括号是告诉编译器这个指针指向一个对象数组,同时也告诉编译器正确的对象地址调用对象的析构函数,如果没有方括号,那么这个指针就被默认为只是指向一个对象,对象数组中的其它对象的析构函数就不会被调用,结果造成了内存泄露。如果方括号中间放了一个比对象大小还大的数字,那么编译器就会调用无效对象(内存溢出)的析构函数,会造成堆的崩溃。如果方括号中间的数字值比对象数组的大小的小,编译器不能调用足够的多个析构函数,结果会造成内存泄露。

释放单个对象、单个基本数据类型的变量或者是基本数据类型的数组不需要大小参数,释放定义了析构函数的对象数组才需要大小参数。

4、指向对象的指针数组不等同与对象数组:对象数组是指:数组中存放的是对象,只需要delete[]p,即可调用对象数组中每个对象的析构函数释放空间。           指向对象的指针数组是指:数组中存放的是对象的指针,不仅仅要释放每个对象的空间,还要释放每个指针的空间,delete【】p只是释放了每个指针,但是没有释放对象的空间,正确的做法,是通过一个循环,将每个对象释放,然后再把指针释放了

5、缺少拷贝构造函数:两次释放相同的内存是一种错误的做法,同时可能会造成堆的奔溃;按值传递会调用(拷贝)构造函数,引用传递不会调用。

在c++中,如果没有定义拷贝构造函数,那么编译器就会调用默认的拷贝的构造函数,会逐个成员拷贝的方式来复制数据成员,如果是以逐个成员拷贝的方式来复制指针被定义为一个变量的地址赋值给另一个变量。这种隐式的指针赋值结果就是两个对象拥有拥有指向同一个动态分配的内存空间的指针。当释放第一个对象的时候,它的析构函数就会释放与该对象有关的动态分配的内存空间,而释放的第二个对象的时候,它的析构函数就会释放相同的内存,这样是错误的。

所以,如果一个类里面有指针成员变量,那么必须显示的写复制构造函数和重载赋值运算符,要么禁用拷贝构造函数和重载赋值运算符。

6、缺少重载赋值运算符:这个问题与5相同,也是成员拷贝的方式复制对象,如果这个类的大小是可变的,那么就造成=内存泄露。

8、没有将基类中的析构函数定义为虚函树:当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数不会被调用,子类的资源没有被正确释放,因此造成内存泄露。

野指针:指向被释放的或者访问受限内存的指针。

造成野指针原因:

1.指针变量没有被初始化(如果值不定,可以初始化为NULL)

2、指针被free或者delete后,没有被置为NULL,free和delelte只是把指针指向的内存释放,并没有把指针本事干掉,此时指针指向的是“垃圾”内存。释放后的指针应该被置为NULL;

3.指针操作超越了变量的作用范围,比如返回指向栈内存的指针就是野指针。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值