初始化静态指针结果 <undefined value>

Initialize a static Pointer results in <undefined value>

我有一个关于托管 C++ 中的指针的初学者问题,这让我很头疼。我正在创建一个元素列表,一个指针应该显示该列表的当前元素。

问题是,当我将第一个元素分配给这个列表时,我想用我的指针 ("varPointer = &firstElem") 引用这个列表的开头。但是在那之后,指针就没有任何价值了。

这是我的代码的简化版本:

ref class ElementClass
{
public:
    value struct Element
    {
        //some items here ...;
        Element *Next, *Previous;
    };
    ...
}

ref class Queue
{
 public:
      static Element* queue;

      static void AddElem(Element* elem)    {
        //Check, if queue is empty
        if (queue == nullptr) {
            queue = elem;
            queue->Previous = nullptr;
         }
         else {             
            queue->Next = elem;
            elem->Previous = queue;
            queue = elem;           
         }
    }
}

程序没有抛出任何错误,在下一次迭代中列表似乎仍然是空的。 即使我用 "static Element* queue = 0" 或队列指针始终具有的东西显式初始化队列。使用 "Element" 的实例进行初始化是不可能的(“类型 'interior_ptr' 的值不能用于初始化类型 'Element *' 的实体)。为此我添加了:

...
public:
    static Element^ tmpElem = gcnew Element();
    static Element* queue = &tmpElem;
...

该程序从不使用 else 语句。 我感谢任何形式的帮助。提前谢谢大家。

(我对一般的编程很熟悉,但顺便说一句,我是C++的新手。)

好的。这很有教育意义。

因此,如果您使用传统的非托管指针

Element *Next = nullptr, *Previous = nullptr;

然后使用按值传递

static void AddElem(ElementClass::Element elem) {
    //Check, if queue is empty
    if (queue == nullptr) {
        queue = &elem;
        queue->Previous = nullptr;
    }
    else {
        queue->Next = &elem;
        elem.Previous = queue;
        queue = &elem;
    }
}

卡布洛伊! elem 在其进入的途中被复制,将超出范围并在退出的途中被销毁,或者被标记为销毁并在不久的将来的某个时候被垃圾收集器销毁。我不确定这个,但它会在你完成之前被摧毁并且很可能。这会留下一堆指向无效内存的指针。如果程序没有崩溃,那不是因为它有效。是你运气不好,貌似成功了

如果你一直回到 C 风格:

Element *Next = nullptr, *Previous = nullptr;

然后传入一个非托管指针

static void AddElem(ElementClass::Element * elem) {
    //Check, if queue is empty
    if (queue == nullptr) {
        queue = elem;
        queue->Previous = nullptr;
    }
    else {
        queue->Next = elem;
        elem->Previous = queue;
        queue = elem;
    }
}

它可以工作,但您必须手动完成所有内存管理。没有垃圾回收。

如果您使用托管指针,您将获得托管内存。很棒的东西。

Element ^Next = nullptr, ^Previous = nullptr;

然后

static void AddElem(ElementClass::Element elem) {
    //Check, if queue is empty
    if (queue == nullptr) {
        queue = elem;
        queue->Previous = nullptr;
    }
    else {
        queue->Next = elem;
        elem.Previous = queue;
        queue = elem;
    }
}

据我所知,它存储并管理 elem 的副本,使副本保持活动状态。原始元素不受影响。它不知道它被链接了,因为它没有。副本已链接。这可能就是您所需要的。看到 Element 是一个值类型,这应该是你想要的。

否则请使用端到端托管指针。

static void AddElem(ElementClass::Element ^ elem) {
    //Check, if queue is empty
    if (queue == nullptr) {
        queue = elem;
        queue->Previous = nullptr;
    }
    else {
        queue->Next = elem;
        elem->Previous = queue;
        queue = elem;
    }
}

请注意,我没有更改任何链表逻辑。效果很好。