(2)、向新开辟的空间拷贝数据时,为什么不能用memcpy? 先来看一段代码:
void _CheckCapacity() { if (_size == _capacity) { _capacity = _capacity * 2 + 3; T* tmp = new T[_capacity]; if (_a) { memcpy(tmp, _a, sizeof(T)*_size); /* for (size_t i = 0; i < _size; ++i) { tmp[i] = _a[i]; }*/ delete[] _a; } _a =tmp; } } 与之前的函数相比,这个_CheckCapacity()函数中用的是memcpy进行拷贝,而非for循环,做了这样的变化之后,我们给出两个测试用例,看看会出现什么样的结果? 同样给出测试函数1: void TestStack1(){ Stack<int> s1; s1.Push(1); s1.Push(2); s1.Push(3); s1.Push(4); while (!s1.empty()) { cout << s1.Top() << endl; s1.Pop(); }}该函数的输出结果如下: 由上图可知,输出正常,而当我们将数据类型换成string,会出现什么样的情况呢?
对于以上的异常输出,有两点疑问:一是为什么程序会崩溃?二是为什么唯独第二个字符串输出的是随机值? 先来看第一个问题:
由上图可知,当旧空间中的string对象调用析构函数,将所指向的空间释放了之后,新开辟空间中的string对象的指针就会指向一段未知的空间,变成野指针,因此程序会崩溃。 再来看第二个问题: 对比一下我们可以发现,只有第二个字符串超过了16个字节,而其他的字符串均没有超过16个字节,那为什么超过16个字节就会出现随机值呢?因为string比较常用,因此系统对它进行了优化,即string对象中除了指针以外,还有16个字节的buff,所以一旦string对象所指向的内存空间中存储的数据超过16个字节,就会产生随机值。 二、简述队列 1、概念 队列也是一种线性表结构,
新闻热点
疑难解答