【问题标题】:C++: values of pointers are wrong after returnC ++:返回后指针的值错误
【发布时间】:2021-08-22 14:56:40
【问题描述】:

编辑将代码更改为最小可重现示例

所以我基本上有一个结构和一个创建该结构实例的函数,将它们推入std::vector<Node>,然后返回它。

#include <iostream>
#include <vector>


struct Node {
    int value;
    Node *left;
    Node *right;
};

Node createNodeFamily(Node child1, Node child2) {

    Node parent;
    parent.value = child1.value + child2.value;

    parent.left = &child1;
    parent.right = &child2;

    return parent;
}

std::vector<Node> f(std::vector<Node>& nodes) {
    std::vector<Node> l;
    Node parent = createNodeFamily(nodes[0], nodes[1]);
    l.push_back(parent);

    Node r = l[0];
    std::cout << "correct value of left child node: " << r.left->value << std::endl;
    std::cout << "correct value of right child node: " << r.right->value << std::endl;

    return l;
}


int main() {

    Node child1;
    child1.value = 2;

    Node child2;
    child2.value = 1;

    std::vector<Node> children;
    children.push_back(child1);
    children.push_back(child2);

    std::vector<Node> p = f(children);

    Node parent = p[0];
    //std::cout << parent.value << std::endl;
    std::cout << "wrong value of left child node: " << parent.left->value << std::endl;
    std::cout << "wrong value of right child node: " << parent.right->value << std::endl;


    return 0;
}

在我的例子中的输出:

Printed inside the function:
>> correct value of left child node: 2
>> correct value of right child node: 1
Printed outside the function:
>> wrong value of left child node: 1875944288
>> wrong value of right child node: 16717313

所以该结构有两个属性leftright,它们是指向子节点地址的指针。当我读取那些在testFunction 中打印它们的指针的值时,它们是正确的。 但是当我返回它们并打印它们时,它们看起来像是随机数。

【问题讨论】:

  • 向量中的节点是否指向向量中的其他节点?如果是这样,您将需要重新考虑您的设计。每次在向量上调用 push_back 时,它都会使向量中所有元素的所有引用、指针和迭代器失效,这会破坏节点链接。
  • ...如果这是唯一的问题,您或许可以改用std::list 来克服它。
  • 我不认为这是问题所在,因为我在检查函数内部/返回之前,向量的内容是正确的)。我认为问题在于,当函数停止时,指针的值指向停止存在,因此在读取它们时会给出随机结果@NathanOliver
  • 我认为std::vector&lt;Node&gt; textFunction(std::vector&lt;Node&gt; nodes) 是你的问题。您构建指向nodes 的节点,但nodes 是按值传递的,因此当函数结束时,它内部的所有内容都会消失。如果您使用 std::vector&lt;Node&gt; textFunction(std::vector&lt;Node&gt;&amp; nodes) 可能会解决您的问题。
  • 存储您使用&amp; 获取的指针以供以后使用很少是一个好主意。当函数返回时,createNodeFamily 的两个参数都会被销毁。

标签: c++ pointers struct


【解决方案1】:

如您所见,存储指向堆栈变量的指针通常会导致灾难。当您使用new 时,指针不再用于堆栈变量(它们被存储在堆上),但仍然有点粗略,因为您需要确保在使用时delete 指针完成,并且可能会影响性能,因为您的节点将分散在内存中。

通常在处理带有引用其他元素的元素的向量时,我会尝试存储索引值而不是指针。考虑以下几点:

struct Node {
    int value;
    size_t left_index;
    size_t right_index;
};

Node createNodeFamily(size_t child1_index, size_t child2_index, std::vector<Node>& nodes) {
    Node parent;

    parent.value = nodes[child1_index].value + nodes[child2_index].value;

    parent.left_index = child1_index;
    parent.right_index = child2_index;

    return parent;
}

那么当您需要访问一个节点时,您将使用nodes[index] 而不仅仅是*node

【讨论】:

    【解决方案2】:

    一种解决方案是不使用&amp; 创建指针,而是使用new 创建节点(在createNodeFamily 函数内进行的更改):

    Node createNodeFamily(Node child1, Node child2) {
    
        Node parent;
        parent.value = child1.value + child2.value;
    
        parent.left = new Node;
        parent.left->value = child1.value;
        parent.right->value = child2.value;
    
        return parent;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 2022-11-07
      • 1970-01-01
      • 2021-03-26
      • 1970-01-01
      • 2023-03-17
      • 2014-04-12
      相关资源
      最近更新 更多