【问题标题】:Pointer Copy to Out of Scope c++指向超出范围c ++的指针复制
【发布时间】:2015-12-06 08:11:06
【问题描述】:

今天我回去调查我在一个旧项目中遇到的一个错误。这不完全是一个错误,而是我不知道该怎么做我需要做的事情。不要真的想深入了解项目的细节,因为它老旧、有缺陷、效率低下,更重要的是无关紧要。所以我编写了一个新的示例代码:

#include <iostream>
#include <vector>
#include <time.h>
#include <random>
#include <string>

class myDoc;

class myElement
{
    int myInt;
    std::string myString;
    myElement * nextElement;
    //a pointer to the element that comes immediately after this one
public:
    myElement(int x, std::string y) : myInt(x), myString(y){};
    friend myDoc;
};//an element type

class myDoc
{
    std::vector<myElement> elements;
public:
    void load();
    ~myDoc()
    {
        //I believe i should delete the dynamic objects here.
    }
};// a document class that has bunch of myElement class type objects as members

void myDoc::load()
{
    srand(time(0));
    myElement * curElement;
    for (int i = 0; i < 20; i++)
    {
        int randInt = rand() % 100;
        std::string textInt =  std::to_string(randInt);
        curElement = new myElement(randInt,textInt);
        //create a new element with a random int and its string form

        if (i!=0)
        {
            elements[i-1].nextElement = curElement;
            //assign the pointer to the new element to nextElement for the previous element 
            //!!!!!!!!!!!! this is the part that where i try to create a copy of the pointer
            //that goes out of scope, but they get destroyed as soon as the stack goes out of scope
        }

        elements.push_back(*curElement);// this works completely fine
    }
}

int main()
{
    myDoc newDoc;
    newDoc.load();
    // here in newDoc, non of the elements will have a valid pointer as their nextElement
    return 0;
}

基本概要:我们有一个文档类型,它由我们定义的元素类型的向量组成。在这个例子中,我们将 20 个随机动态分配的新元素加载到文档中。 我的问题/问题:

  1. void myElement::load() 函数结束时,指针和/或其副本超出范围并被删除。我如何保持一份至少在它指向的对象被删除之前保持不变(不是完全静态的,是吗?)?
  2. elements 向量中的对象是原始动态分配的对象还是只是一个副本?
  3. 我用new 分配内存,我应该如何/何时应该delete 他们?

这是我为解释第一个问题而绘制的图片(具体示例不太准确,但问题相同),感谢您的宝贵时间。

【问题讨论】:

标签: c++ pointers vector scope


【解决方案1】:

注意:我假设您想要一个由 myElement 对象组成的向量,其中每个对象都指向它旁边的元素。目前尚不清楚您是否希望elements 中的对象指向它们的副本,无论如何修改代码以实现后者应该很容易

这就是您的代码中发生的情况:

void myDoc::load()
{
   ..
   curElement = new myElement(n,m); // Create a new element on the heap

   ...
   // If this is not the first element we inserted, have the pointer for the
   // previous element point to the heap element 
   elements[i-1].nextElement = curElement;

   // Insert a COPY of the heap element (not the one you stored the pointer to)
   // into the vector (those are new heap elements copied from curElement)
   elements.push_back(*curElement);// this works completely fine
}

所以当myDoc::load() 超出范围时不会删除任何内容,但是您有 内存泄漏错误,因为指针没有指向 @ 中的元素987654326@ 向量,但在您分配的第一个堆元素中。

这也回答了你的第二个问题:它们是复制品。

为了自动释放你的内存,不要泄漏并指向正确的元素,你可能会做类似的事情

class myElement
{
  int a;
  std::string b;
  myElement *nextElement = nullptr;
  //a pointer to the element that comes immediately after this one
public:
  myElement(int x, std::string y) : a(x), b(y){};
  friend myDoc;
};//an element type

class myDoc
{
  std::vector<std::unique_ptr<myElement>> elements;
public:
  void load();
  ~myDoc()
  {}
};// a document class that has bunch of myElement class type objects as members

void myDoc::load()
{
  srand((unsigned int)time(0));
  for (int i = 0; i < 20; i++)
  {
    int n = rand() % 100;
    std::string m = std::to_string(n);
    //create a new element with a random int and its string form
    elements.emplace_back(std::make_unique<myElement>(n, m));

    if (i != 0)
    {
      //assign the pointer to the new element to nextElement for the previous element 
      elements[i - 1]->nextElement = elements[i].get();
    }
  }
}

Live Example

不需要delete 析构函数中的任何内容,因为当myDoc 元素超出范围时,智能指针将被自动销毁(并释放内存)。我相信这可能是您想要做的,因为这些元素无论如何都归 myDoc 类所有。

【讨论】:

  • 感谢您的回答,真的很有帮助。也感谢您的细微更正。一件小事,当时,这是一个家庭作业项目,我不被允许使用智能指针。您认为没有它们的解决方案是否可能/值得研究?
  • @user3402183 当然,您显然可以自己分配内存并在析构函数中管理释放。您可以创建 std::vector&lt;myElement&gt; 并让元素指向向量中的其他元素(C++11 提供就地构造),或者只使用 std::vector&lt;myElement*&gt; 并管理所有分配(除了包含在矢量)你自己
  • 非常感谢,我现在明白了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 2017-05-04
  • 1970-01-01
相关资源
最近更新 更多