简体   繁体   English

C ++指针和变量作用域

[英]c++ pointers and variable scope

I am trying to create a tree structure using some handler functions that are called while reading a stream. 我正在尝试使用一些在读取流时调用的处理函数来创建树结构。 I think the problem is that my variables are created in the function's scope and disappear when the function ends, leaving pointers that point to nothing. 我认为问题在于我的变量是在函数的作用域中创建的,并在函数结束时消失,而使指向任何内容的指针都消失了。

I am not sure what approach to take to keep the objects in memory, whilst still allowing the tree to be scalable. 我不确定采用什么方法将对象保留在内存中,同时仍然允许树可伸缩。

I have made a simplified version of the code: it compiles and runs but the parent-child relationships of the 'Segment' objects are all wrong. 我做了一段简化的代码:它可以编译并运行,但是“段”对象的父子关系都是错误的。

class Segment
{
public:
    Segment* parent;
    list<Segment*> children;
    string name;
};

void OpenSegment(Segment* p_segCurrentseg);
void CloseSegment(Segment* p_segCurrentseg);

int _tmain(int argc, _TCHAR* argv[])
{
    Segment parent;
    parent.name="parent";
    Segment* p_segCurrentseg=&parent;
    OpenSegment(p_segCurrentseg);
    OpenSegment(p_segCurrentseg);
    OpenSegment(p_segCurrentseg);
    CloseSegment(p_segCurrentseg);
    return 0;
}

void OpenSegment(Segment* p_segCurrentseg)
{
    Segment child;
    child.name="child";
    p_segCurrentseg->children.push_front(&child);
    child.parent=p_segCurrentseg;
    p_segCurrentseg=&child;
}

void CloseSegment(Segment* p_segCurrentseg)
{
    p_segCurrentseg=p_segCurrentseg->parent;
}

There are couple of problems in your code. 您的代码中有几个问题。

  1. You are passing p_segCurrentseg by value and assigning to another pointer. 您正在按值传递p_segCurrentseg并分配给另一个指针。 This has no effect on the variable in the calling function. 这对调用函数中的变量没有影响。

  2. As you already suspected, you are trying to assign p_segCurrentseg to point to a variable that will be gone when you return from the function. 正如您已经怀疑的那样,您正在尝试分配p_segCurrentseg指向从函数返回时将消失的变量。

What you can do: 你可以做什么:

  1. Pass p_segCurrentseg by reference to a pointer. 通过引用将p_segCurrentseg传递给指针。

  2. Create an object from the heap and assign p_segCurrentseg to point to it. 从堆中创建一个对象,并分配p_segCurrentseg指向它。

Here's my suggestion for OpenSegment : 这是我对OpenSegment的建议:

void OpenSegment(Segment*& p_segCurrentseg)
{
    Segment* child = new Segment;
    child->name="child";
    p_segCurrentseg->children.push_front(child);
    child->parent=p_segCurrentseg;
    p_segCurrentseg=child;
}

The problem is in the OpenSegment() method, particularly in these 3 lines: 问题出在OpenSegment()方法中,特别是在以下3行中:

Segment child;
child.name="child";
p_segCurrentseg->children.push_front(&child);

First, child is a local variable and created on the stack. 首先,child是一个局部变量,在堆栈上创建。 You then push the address of child into your list. 然后,您将孩子的地址推入列表。 When OpenSegment() returns, the address of child contains garbage since storage for local variables are deallocated. 当OpenSegment()返回时,子对象的地址包含垃圾,因为已释放了局部变量的存储空间。

The solution is to define child as a pointer to Segment, create it on the heap so it lives even after OpenSegment() returns. 解决方案是将child定义为指向Segment的指针,并在堆上创建它,以便即使在OpenSegment()返回后它也仍然存在。 You have to make sure to deallocate its memory too. 您还必须确保重新分配其内存。 The proper place is to define a destructor for your Segment class. 正确的地方是为您的Segment类定义一个析构函数。 In it, iterate through the list (of children segments) and deallocate the memory for each child. 在其中,迭代(子段的)列表,并为每个子段分配内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM