无法在struct中填充向量

时间:2013-08-07 20:03:10

标签: c++ vector

我是C ++的新手所以请耐心等待。

我做了一个看起来像这样的结构:

struct node{
   double startPoint;
   double endPoint;
   vector<node*> children;

   void addChild(node *aNode){
      children.push_back(aNode);
   }
   void addPoints(double start, double end){
      startPoint = start;
      endPoint = end;
   }
};

在我的计划中,我有以下内容:

vector<node*> data;
....
node *temp = (node*)malloc(sizeof(node));
temp->addPoints(lexical_cast<double>(numbers[0]), lexical_cast<double>(numbers[1]));
data[index]->addChild(temp);

其中“Index”是矢量数据的索引。 lexical_cast内容正在将这些数字从字符串转换为双倍。

一切都有效,直到addChild(temp)行。

终端吐了出来:

First-chance exception at 0x585b31ea (msvcr90d.dll) in Tree.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1.
Unhandled exception at 0x585b31ea (msvcr90d.dll) in Tree.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1.

但我不知道如何处理。

3 个答案:

答案 0 :(得分:2)

malloc分配一些空间,但不会在其中放置任何内容。它适用于普通旧数据结构(或简单的可初始化类),而在C语言中,这就是你所拥有的一切。

在C ++中,您有类,如std::vector等,需要正确构造才能建立一些不变量。这是通过对具有自动存储持续时间的对象的直接声明来完成的,但对于动态分配的对象,您需要使用new而不是malloc

例如,

std::vector<int> global;    // (1)
void foo() {
    std::vector<int> local; // (2)
    std::vector<int> *bad = malloc(sizeof(*bad));  // (3)
    std::vector<int> *good = new std::vector<int>; // (4)
    std::unique_ptr<std::vector<int>> better(new std::vector<int>); (5)
}
  1. 很好 - 这个全局被自动初始化(我的意思是构造函数被调用)
  2. 很好 - 这个局部变量也会自动构建,并在foo退出后立即销毁
  3. 你不能使用bad来做任何事情,因为你调用的任何方法都会假设构造函数已经运行了,而且它没有
    • 好的,如果没有使用展示位置新明确构建,则无法使用bad。你不应该这样做,它只适用于你做自定义分配的聪明或棘手的事情。
  4. 这没关系(但请注意你必须手动删除它 - foo有内存泄漏)
  5. 这样更好 - 您无需手动清理

  6. 现在,请注意您的node有一个构造函数。在这种情况下,它是自动生成的,除了调用vector构造函数之外什么都不做。不过,您需要调用它,这意味着使用new动态分配node

    所以,你的程序应该看起来更像:

    std::vector<std::unique_ptr<node>> data;
    ...
    std::unique_pre<node> temp(new node);
    temp->addPoints(...);
    data[index]->addChild(temp);
    

    注意我假设data[index]有效(我从addChild看到您知道如何填充向量),并且unique_ptr实施的单一所有者模型是合适的

答案 1 :(得分:1)

就我看到的代码而言,您永远不会将任何节点添加到data数组

data.push_back(something);

因此访问data[index]将超出阵列的已分配内存。在您尝试在该块中设置内存之前不会抱怨(通过addChild尝试将元素推入children数组)。

答案 2 :(得分:0)

  1. 我建议您在向量中存储node而不是node*,这样您就无需自行管理内存。
  2. 这是C ++,因此您不必为可以使用新节点的节点malloc空间如下:
    Node * n = new Node();

  3. New更好,因为它调用构造函数并分配空间,而malloc只执行后者。


  4. 您没有显示太多代码,但我会像这样重构节点类。

    struct node{
       double startPoint;
       double endPoint;
       vector<node> children;
       node(){} //add default constrcutor    
       void addChild(node aNode){
          children.push_back(aNode);
       }
       node & operator=(const node & n) {
           startPoint = n.startPoint;
           endPoint = n.endPoint;
           return *this;
       }
       node(double start, double end): startPoint(start),endPoint(end){
       } //in c++ you have constructors which this should have been in the first place
         //constructors are used for initializing objects
    };  
    
    1. 这更好的是现在你无法通过添加子nullptr来避免代码中出现很多问题。你现在也有一个构造函数。现在您可以添加这样的节点。
    2. node temp(start,end); data[index]=temp;

      1. 您现在有一个构造函数addPoints应该是第一个
      2. 我还创建了一个赋值运算符

      3.   

        使用在堆栈上分配内存而不使用new的编码样式称为RAII,是学习c ++和生成异常安全代码的重要技术,这是我提倡的不是主要原因存储node*