【问题标题】:Constructor for custom vector class assigning extra garbage values to pointers自定义向量类的构造函数,将额外的垃圾值分配给指针
【发布时间】:2020-12-01 04:05:39
【问题描述】:

你好,又是一个向量类问题。

这是我的 .CPP 文件

#include "myStringVector.hpp"

  void myStringVector::reserve(int n){
    if(!base){
      base = allocate<myString>(n);
      last = base;
      limit = base+n;
    }
    else{
      myString *p = allocate<myString>(n); //new base
      myString *q = p; //new last
      limit = p + n; //new limit
      myString *i = uninitialized_copy(base, last, q);
      destroy(i);
      deallocate(base);
      base = p; //update base
      last = q; //update last
    }
  }

  myStringVector::myStringVector(){
    this->reserve(0);
  }

  myStringVector::~myStringVector(){
    if(!base){
      deallocate(base);
      deallocate(last);
      deallocate(limit);
    }
    else{
      base = initialized_destroy(base, last);
      deallocate(base);
      deallocate(last);
      deallocate(limit);
    }
  }

  myStringVector::myStringVector(const std::initializer_list<myString>& list){
    std::cout << list.size() << "\n";
    this->reserve(list.size());
    last = uninitialized_copy(list.begin(), list.end(), last);
  }

  int myStringVector::size() const{
    return (last - base);
  }

  bool myStringVector::empty() const{
    return (this->size() == 0);
  }

  myString myStringVector::operator[](int index){
    return *(base+index);
  }

这是我的 .HPP 文件

#ifndef MYSTRINGVECTOR_HPP
  #define MYSTRINGVECTOR_HPP

  #include "myString.hpp"

  class myStringVector{
  private:
    myString *base = nullptr;
    myString *last = nullptr;
    myString *limit = nullptr;
  public:
    void reserve(int);
    myStringVector();
    ~myStringVector();
    myStringVector(const std::initializer_list<myString>&);
    int size() const;
    bool empty() const;
    myString operator[](int);

  };

  #endif //MYSTRINGVECTOR_HPP_INCLUDED

也使用这些函数...

template<typename T>
  inline T* uninitialized_copy(T const* first, T const* last, T* out)
  {
    while (first != last) {
      construct(out, *first);
      ++out;
      ++first;
    }
    return out;
  }

...

template<typename T>
  inline T* initialized_destroy(T* first, T* last)
  {
    while (first != last) {
      destroy(first);
      ++first;
    }
    return first;
  }

...

template<typename T, typename... Args>
  inline T* construct(T* p, Args&&... args)
  {
    return new (p) T(std::forward<Args>(args)...);
  }

...

template<typename T>
  inline T* allocate(int n)
  {
    return reinterpret_cast<T*>(::operator new(n * sizeof(T)));
  }

还有……

template<typename T>
  inline void deallocate(T* p)
  {
    ::operator delete(p);
  }

我的主要做这个...

{
myStringVector v;
assert(v.empty());
std::cout << "Passed default ctor" << std::endl;
myStringVector v1 {"a", "b", "c"};
myStringVector v2 {"d", "e", "f"};
std::cout << v1.size() << " " << v2.size() << "\n";
std::cout << v1[0] << v1[1] << v1[2];
}

myString 只是一个自定义字符串类。它就像一个普通的字符串类。

当我运行 main 时,我希望 v1 能够保存 a、b 和 c。和 v2 来保存 d、e 和 f。但这就是我得到的……

ap÷bp÷cp÷

所以看起来它在每个字符之后用额外的垃圾初始化每个索引。我试过不使用reserve() 和uninitialized_copy 直接初始化,它工作正常。但是,我的教授要求我使用这些令人困惑的内存管理功能。我假设我使用的函数不正确,但是当编译器没有给我任何错误时,很难知道要修复什么。

如果有人可以帮助我了解我做错了什么以及为什么我会看到垃圾值,我会非常感激。

谢谢!

【问题讨论】:

  • 抱歉,在回答问题之前我看到了一堵代码墙,所以我跳过了这个。

标签: c++ initializer-list garbage class-constructors


【解决方案1】:

你说

myString 只是一个自定义字符串类

但是你是怎么实现的呢?

我的直接印象是您的自定义字符串类正在复制字符并且未能在它们的末尾放置终止的 null。

另一个关键点是您使用的是cout,因此您需要知道您的自定义字符串是如何编写的。例如:如果您有一个operator const char*,那么它将被拾取,并且流输出将期待一个真正的 C 字符串,并以 null 结尾。

见oofString output

ostream& 
operator<<(ostream& os, const oofString& str)
{
    os << str.chars();
    return os;
}

其中chars()定义为:

inline const char*
oofString::chars() const
{
    if (mBody)
        return mBody;
    else
        return "";
}

我在这个问题中看到的任何内容都没有表明myStringVector 是问题的根源。

【讨论】:

  • 那是公平的,字符串类通常工作得很好,但我会尝试与普通字符串类相同的代码,看看是否有问题。
  • 我在 OOFILE 中实现了我自己的跨平台字符串,并进行了很多改进,但它也维护了一个带有空终止符的缓冲区和一个长度,呃,大约 28 年前。所以我很确定我用空值犯了这个错误。 github.com/AndyDentFree/oofile/blob/master/source/core/…
  • 我将其切换为与 一起使用,现在可以使用。所以我想可以肯定地说 myString 坏了? -- 我会检查链接!
猜你喜欢
  • 1970-01-01
  • 2016-01-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2012-10-17
  • 2013-01-21
  • 2022-01-18
相关资源
最近更新 更多