【问题标题】:Why does a pointer change address when I call a function?为什么调用函数时指针会改变地址?
【发布时间】:2021-03-18 04:42:44
【问题描述】:

我正在尝试用 C++ 实现一个链表。

int main() {
    ListaEnlazada <int> l1 (5);
    //l1.imprimir();
    l1.insertar(10, 0);
    l1.imprimir();
}

template<typename T>
class ListaEnlazada {
public:
    ListaEnlazada(T inicial) {
        cabeza = new Nodo <T> (inicial);
        tamano = 1;
    }
    void insertar(const T &valor, size_t indice) {
        if(indice >= 0 && indice <= tamano) {
            Nodo <T> *nodo_previo = NULL;
            Nodo <T> *nodo_actual = cabeza;
            for(size_t i = 0; i < indice; i++) {
                nodo_previo = nodo_actual;
                nodo_actual = nodo_actual->obtener_siguiente();
            }               
            Nodo <T> nuevo_nodo (valor);
            if(nodo_previo == NULL) {
                cabeza = &nuevo_nodo;
                nuevo_nodo.establecer_siguiente(nodo_actual);
                tamano += 1;
            }
            else if(nodo_previo != NULL && nodo_actual != NULL) {
                nodo_previo->establecer_siguiente(&nuevo_nodo);
                nuevo_nodo.establecer_siguiente(nodo_actual);
                tamano += 1;
            }
            else if(nodo_actual == NULL) {
                nodo_previo->establecer_siguiente(&nuevo_nodo);
                nuevo_nodo.establecer_siguiente(nodo_actual);
                tamano += 1;
            }
            else {
                std::cout << "Error: ocurrió algo inesperado." << std::endl;
            }
        }
        else {
            std::cout << "Error: el índice máximo permitido actualmente es: " << tamano << "." << std::endl;
        }
    }
    void imprimir() {
        Nodo <T> *nodo_actual = cabeza;
        for(size_t i = 0; i < tamano; i++) {
            std::cout << nodo_actual->obtener_elemento() << " ";
            nodo_actual = nodo_actual->obtener_siguiente();
        }
        std::cout << std::endl;
    }
private:
    Nodo <T> *cabeza;
    size_t tamano;
};

template<typename T>
class Nodo {
public:
    Nodo(T elem) {
        elemento = elem;
        sig_elem = NULL;
    }

    Nodo *obtener_siguiente() {
        return sig_elem;
    }

    void establecer_siguiente(Nodo *sig_ptr) {
        sig_elem = sig_ptr;
    }

    T obtener_elemento() {
        return elemento;
    }
private:
    T elemento;
    Nodo <T> *sig_elem;
};

显然我的初始化和插入元素的功能工作正常。但是在程序执行打印函数之后,指向列表中第二个元素的指针立即改变了它指向的地址,并且第二个元素也改变了它的值。 我已经使用了调试模式,注意到在索引 0 处插入元素 10 后一切正常,但在程序执行打印功能后立即出现错误。

【问题讨论】:

  • 在打印功能之后,你马上就要让你的头从堆栈上掉下来了。是否有您排除的代码?您能否更好地表明您如何知道事情正在发生变化?
  • 我没有排除任何代码,除了标题。使用调试模式,我看到在进入打印函数之前,列表头部的sig_elem值为0x55555556aeb0,进入函数后,它的值为0x7fffffffdc50。它在程序结束时打印的值是 10 -962292416 而不是 10 5。

标签: c++ pointers linked-list


【解决方案1】:

这是你的问题:

    Nodo <T> nuevo_nodo (valor);
    if(nodo_previo == NULL) {
        cabeza = &nuevo_nodo;
        nuevo_nodo.establecer_siguiente(nodo_actual);
        tamano += 1;
    }

这个变量只是坐在堆栈上。它会消失的。你可能真的需要在这里做一个new Nodo&lt;t&gt;。

【讨论】:

    【解决方案2】:

    问题在于您的插入函数 - nuevo_nodo 被声明为局部变量。只要您在insertar 中,它似乎就可以正常运行,但是一旦您离开,您的新节点就会丢失并且头部指向垃圾数据。

    将其更改为 new Nodo&lt;T&gt;(并在代码后面更改对它的引用)可以解决您的问题。

        void insertar(const T &valor, size_t indice) {
            if(indice >= 0 && indice <= tamano) {
                Nodo <T> *nodo_previo = NULL;
                Nodo <T> *nodo_actual = cabeza;
                for(size_t i = 0; i < indice; i++) {
                    nodo_previo = nodo_actual;
                    nodo_actual = nodo_actual->obtener_siguiente();
                }
                Nodo <T> *nuevo_nodo = new Nodo<T>(valor);  //put it on the heap
                if(nodo_previo == NULL) {
                    cabeza = nuevo_nodo;
                    nuevo_nodo->establecer_siguiente(nodo_actual);
                    tamano += 1;
                }
                else if(nodo_previo != NULL && nodo_actual != NULL) {
                    nodo_previo->establecer_siguiente(nuevo_nodo);
                    nuevo_nodo->establecer_siguiente(nodo_actual);
                    tamano += 1;
                }
                else if(nodo_actual == NULL) {
                    nodo_previo->establecer_siguiente(nuevo_nodo);
                    nuevo_nodo->establecer_siguiente(nodo_actual);
                    tamano += 1;
                }
                else {
                    std::cout << "Error: ocurrió algo inesperado." << std::endl;
                }
            }
            else {
                std::cout << "Error: el índice máximo permitido actualmente es: " << tamano << "." << std::endl;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2016-04-17
      • 1970-01-01
      • 2020-03-19
      • 2016-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多