为啥调用函数时指针会改变地址?
Posted
技术标签:
【中文标题】为啥调用函数时指针会改变地址?【英文标题】: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。 【参考方案1】:这是你的问题:
Nodo <T> nuevo_nodo (valor);
if(nodo_previo == NULL)
cabeza = &nuevo_nodo;
nuevo_nodo.establecer_siguiente(nodo_actual);
tamano += 1;
这个变量只是坐在堆栈上。它会消失的。你可能真的需要在这里做一个new Nodo<t>
。
【讨论】:
【参考方案2】:问题在于您的插入函数 - nuevo_nodo
被声明为局部变量。只要您在insertar
中,它似乎就可以正常运行,但是一旦您离开,您的新节点就会丢失并且头部指向垃圾数据。
将其更改为 new Nodo<T>
(并在代码后面更改对它的引用)可以解决您的问题。
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;
【讨论】:
以上是关于为啥调用函数时指针会改变地址?的主要内容,如果未能解决你的问题,请参考以下文章
C语言基础:指针相关概念(指针的算术运算 指针数组指向指针的指针 传递指针给函数 从函数返回指针 )为啥C 语言不支持在调用函数时返回局部变量的地址?