Pointers 初始化静态指针会导致<;未定义值>; 我在管理C++中只使用指针的初学者问题,这让我头痛。我正在创建一个元素列表,指针应该显示该列表的当前元素

Pointers 初始化静态指针会导致<;未定义值>; 我在管理C++中只使用指针的初学者问题,这让我头痛。我正在创建一个元素列表,指针应该显示该列表的当前元素,pointers,c++-cli,Pointers,C++ Cli,问题是,当我将第一个元素分配给这个列表时,我想用指针(“varPointer=&firstElem”)引用这个列表的开头。但是在那之后,指针就没有任何值了 以下是我的代码的简化版本: ref class ElementClass { public: value struct Element { //some items here ...; Element *Next, *Previous; }; ... } ref class Q

问题是,当我将第一个元素分配给这个列表时,我想用指针(“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++是新手)。

< P>好的。这是教育性的。< /P> 因此,如果使用传统的非托管指针

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;
    }
}
然后使用传递值

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;
    }
}
Kablooey!
elem
在它进入的过程中被复制,并将超出范围,在返回的过程中被销毁,或者被标记为销毁,并在不久的将来由垃圾收集器在某个时候死亡。我不确定这一点,但它将被销毁,并且很可能在您完成它之前被销毁。这会留下一堆指向无效备忘录的指针如果程序没有崩溃,那不是因为它起作用了,而是因为你运气不好,看起来它起作用了

如果您一直回到C风格:

Element *Next = nullptr, *Previous = nullptr;
然后传入一个非托管指针

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;
    }
}
据我所知,它存储并管理元素的副本,使副本保持活动状态。原始元素不受影响。它不知道它已链接,因为它未被链接。副本已链接。这可能是您所需要的全部。鉴于
元素
是一种值类型,这应该是您想要的

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

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;
    }
}

注意,我没有改变任何链表逻辑。这很好。< /P>但是我是C++新手,我对这个“管理C++”新手。“你所发布的内容肯定不是C++,至少是ANSI C++。<代码>元素*NETX,*BASEN;<代码>具有指向可能已分配或管理的数据的非托管指针。小心混合托管和非托管指针。很可能这就是编译器警告的。在

void AddElem(Element elem)
elem
中,按值传递。这将导致
elem
成为传入内容的临时副本,在退出函数时将被销毁<代码>队列=&elem存储指向此临时副本的指针,并在函数结束和
elem
被销毁后指向无效内存。这里是龙。我以为结构和类总是通过引用传递的?恐怕不是。必须明确调用C++中的PASS引用。对内部指针做了更多的阅读。这可能会有帮助:值类型( ValueStult)就像C++类一样工作,因为它们是通过值传递的。GC不需要涉及局部值类型变量。它清理值类型的唯一时间是当它们是自身被收集的引用类型(
ref class
)的一部分时。这包括装箱的值。值类型只是引用类型内存的一部分,因此会被清除。C++ + CLI(不管理C++——这是一个遗留物)是一种特殊的野兽:你得到C++的复杂性加上CLR的复杂性,你需要把两者混合在一起。我将元素的所有实例从值类型或非托管指针“*”更改为托管指针“^”。现在很好用。显然我误解了管理指针。。。感谢你们的帮助,特别是@user4581301,他显然花了很长时间进行研究。