一个primer习题问题

adventurelw 2009-05-08 08:59:14
仍然是实现Vector容器,采用operator new,operator delete, placement new
问题有关代码如下:

#include <algorithm>
#include <new>
#include <cstddef>

template <typename T>
class Vector
{
public:
typedef T * iterator;
typedef std::size_t size_type;
private:
iterator element;
iterator first_free;
iterator end_of_storge;
void destroy();//销毁元素及释放内存
template <typename iter>
void copy_elem(iter b, iter e);//复制元素到指定位置
void reallocate();//重新分配足够空间,一般是原来空间的两倍
public:
Vector() : element(0), first_free(0), end_of_storge(0) {}
template <typename iter>
Vector(iter b, iter e);//使用同类模版构造
Vector(size_type n, const T &t);
Vector(const Vector &vec);//复制构造
~Vector() { destroy(); }
Vector &operator =(const Vector &vec);//赋值重载
void push_back(const T &t);
size_type size() const { return first_free - element; }
void resize(size_type new_size, const T &t);
void reserved(size_type n);//重新分配空间
size_type capacity() const { return end_of_storge - element; }
T &operator [](size_type i) { return *(element + i); }
const T &operator [](size_type i) const { return *(element + i); }
iterator begin() { return element; }
const iterator begin() const { return element; }
iterator end() { return first_free; }
const iterator end() const { return first_free; }
};

template <typename T>
void Vector<T>::reallocate()
{
size_type old_size = size();
size_type new_size = 2 * (std::max<size_type>(old_size, 1));
iterator newelement = static_cast<T *>(operator new[](new_size * sizeof(T)));
iterator pold = element;
iterator pnew = newelement;
while(pold != first_free)
new (pnew++) T(*pold++);//定位new构造
destroy();
element = newelement;
first_free = element + old_size;
end_of_storge = element + new_size;
}

template <typename T>
void Vector<T>::push_back(const T &t)
{
if(first_free = end_of_storge)
reallocate();
new (first_free) T(t);
++first_free;
}

template <typename T>//没有问题
void Vector<T>::reserved(size_type n)
{
size_type old_size = size();
iterator newelement = static_cast<T *>(operator new[](sizeof(T) * n));
iterator pold = element;
iterator pnew = newelement;
while(pold != first_free)
new (pnew++) T(*pold++);
destroy();
element = newelement;
first_free = element + old_size;
end_of_storge = element + n;
}

编译没有问题,和如下主函数一起

#include "stdafx.h"
#include "template.h"
int main()
{
std::ofstream fout("note.txt");
if(!fout.is_open())
{
std::cerr << "oh.\n";
exit(EXIT_FAILURE);
}
Vector<int> ivec;
std::cout << "capacity = " << ivec.capacity() << std::endl;
fout << "capacity = " << ivec.capacity() << std::endl;
ivec.reserved(2);
std::cout << "capacity = " << ivec.capacity() << std::endl;
fout << "capacity = " << ivec.capacity() << std::endl;
int n;
while(std::cin >> n)
ivec.push_back(n);
for(Vector<int>::size_type i = 0; i < ivec.size(); ++i)
{
std::cout << ivec[i] << " ";
fout << ivec[i] << " ";
}
std::cout << std::endl;
return 0;
}

为了记录结果,用了ofstream,与问题无关
最后的运行结果:
capacity = 0
capacity = 2
-842150451 -842150451 4 -842150451 5 -842150451 -842150451 -842150451 6 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 7 17

实际只输入了4,5,6,7四个数,最后容器的size为17
个人初步认为是push_back成员的问题,其余没有列出实现的成员都单独测试过,没有问题,并且,push_back在不使用reserved先分配两个元素空间的情况下,会发生运行中止的错误,错误发生在输出容器元素那里,说什么没有正确的值。而这种情况下,运行是没有问题,就是并非预期结果。
求解疑惑,谢谢大家。
...全文
147 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
amossavez 2009-05-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 adventurelw 的回复:]
引用 6 楼 ltc_mouse 的回复:
C/C++ codetemplate <typename T>voidVector <T>::push_back(constT&t)
{if(first_free=end_of_storge)///这里有错吧?应该要用==吧?reallocate();new(first_free) T(t);++first_free;
}

我好恨,看了十七八遍都没看出来。。。
[/Quote]

呵呵,往往是这种小地方容易出错!!
adventurelw 2009-05-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ltc_mouse 的回复:]
C/C++ codetemplate<typename T>voidVector<T>::push_back(constT&t)
{if(first_free=end_of_storge)///这里有错吧?应该要用==吧?reallocate();new(first_free) T(t);++first_free;
}
[/Quote]
我好恨,看了十七八遍都没看出来。。。
ltc_mouse 2009-05-08
  • 打赏
  • 举报
回复

template <typename T>
void Vector<T>::push_back(const T &t)
{
if(first_free = end_of_storge) ///这里有错吧?应该要用==吧?
reallocate();
new (first_free) T(t);
++first_free;
}

liliangbao 2009-05-08
  • 打赏
  • 举报
回复
帮顶~
adventurelw 2009-05-08
  • 打赏
  • 举报
回复
我的实现和答案有些不一样,并且也对了。有一点不同,看不出问题在哪
不同的地方在reallocate成员的实现部分
iterator pold = element;
iterator pnew = newelement;
while(pold != first_free)
new (pnew++) T(*pold++);//定位new构造


答案用的是std::uninitialized_copy(element, first_free, newelement);
实现结果仍然没有不一样。。。。。。
  • 打赏
  • 举报
回复
http://download.csdn.net/source/1287127

你下来自己研究吧。
  • 打赏
  • 举报
回复
算了,做做好人,上传到下载频道吧。
  • 打赏
  • 举报
回复
是第4版,18.1跟18.6的题目吧。

现在有答案可以下了。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧