变量作为参考不保留
Variable as reference not staying
所以我读了这个帖子和许多其他帖子:函数不改变传递的指针c++
但我仍然不能解决我的问题。我有一个这样声明的函数:
void test(list<int*> *listNodes){
int v=5;
(*listNodes).push_back(&v);
(*listNodes).push_back(&v);
(*listNodes).push_back(&v);
for(int a = 0; a < (*listNodes).size(); a ++){
std::list<int*>::iterator i = (*listNodes).begin();
advance(i, a);
int *totry = *i;
cout << *totry;
cout << ",";
}
}
这工作,并打印良好,我的意思是:listNodes变量有3个元素,所有的5。但是,当该函数返回时,这些值不会更新。我的意思是这个变量有垃圾。我在另一个例子中这样调用这个函数:
void create(list<int*> listNodes){
test(&listNodes);
for(list<int*>::const_iterator it=listNodes.begin();
it!=listNodes.end(); it++){
int *show=*it;
cout << *show << 'n';
}
}
同样,在这个函数中,cout将输出内存垃圾,而不是输出3个5。关于我应该如何继续,当功能测试回来,我有列表填充的想法吗?
我相信您正在考虑的问题(与此代码中的其他问题相反)实际上并不是您所想的。列表保持它的值,问题是它的值指向垃圾内存。
当你这样做的时候:
int v=5;
(*listNodes).push_back(&v);
(*listNodes).push_back(&v);
(*listNodes).push_back(&v);
你将v的地址的三个副本放入列表中。您已经将v声明为仅在此函数期间存在的堆栈变量。当您在function test
中打印listNodes的元素所指向的值时,该变量仍然存在于该内存位置中。
当您稍后打印出function create
中listNodes的元素所指向的值时,该变量已经超出了作用域,并已被其他东西使用,因此产生了垃圾。
这里有两个可能的解决方案可以考虑:
- 用
list<int>
代替list<int *>
。如果您想要做的只是存储一个整数列表,那么这就是可行的方法。 另一方面,如果您确实需要存储指向这些整数的指针,则需要从堆中分配内存:
int* v = new int(); // allocate an int on the heap *v = 5; // store 5 in that int (*listNodes).push_back(v); // save the pointer to the allocated // memory in *listNodes etc
对于现代c++来说,这并不是很好,因为您通常根本不想处理原始指针,但它说明了我认为您正在努力解决的问题。
在此代码中,
void create(list<int*> listNodes){
listNodes=teste(&listNodes);
白马王子;形式参数listNodes
是按值传递的。这意味着该函数接收到一个拷贝,无论该是在调用实例中作为实际参数传递的。对该副本的更改将不会反映在实际参数中。
对teste
的调用不会调用test
函数,因为它是一个不同的名称。
在某种程度上这是好的,因为test
被声明为void
函数,所以它不能返回任何东西。
但这也很糟糕,因为这意味着你的代码中非常关键的一部分,即实际调用的teste
函数,根本没有显示在你的问题中。
test
函数
void test(list<int*> *listNodes){
int v=5;
(*listNodes).push_back(&v);
for(int a = 0; a < (*listNodes).size(); a ++){
std::list<int*>::iterator i = (*listNodes).begin();
advance(i, a);
int *totry = *i;
cout << *totry;
cout << ",";
}
printf("n");
}
白马王子;有很多问题。
从顶部开始,在c++中指针参数
void test(list<int*> *listNodes){
白马王子;最好是通过引用传递的参数。指针可以为空。这对这个函数没有意义,代码也没有准备好处理它。
在 int v=5;
(*listNodes).push_back(&v);
白马王子;局部变量的地址被压入返回的列表中。但是在这一点上,局部变量不再存在,你有一个悬空指针,一个曾经指向某个东西的指针,但不再存在了。如果调用者使用了那个指针,那么你就有了未定义行为。
接下来,这个循环,
for(int a = 0; a < (*listNodes).size(); a ++){
std::list<int*>::iterator i = (*listNodes).begin();
advance(i, a);
白马王子;将工作,但它不必要有O(n2)复杂度,即执行时间。
只使用迭代器进行迭代。这就是迭代器的作用。迭代。
总而言之,你看到的垃圾是由于未定义的行为。
别那么做
- 有根的二进制搜索树.保留与其父级的链接
- 为多个会话保留XPtr
- C++错误消息*成员参考.**初学者*
- 在决定是通过参考还是通过价值时,尺寸真的是一个问题吗
- 参考资源文件VC++中的$(SolutionDir)
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 保留对其他类的成员函数的引用
- 为什么在运算符重载时需要参考?
- 指针保留字符串
- 是否有内置方法可以强制转换为不同的基础类型,但保留常量限定符?
- 如何让 GCC/Clang 在保留标识符上出错
- 使 \page 和 \subpage 参考 doxygen 中的方法文档
- 必须为 C++20 协程帧保留多少内存?
- 如何将一个窗口保留在另一个应用程序窗口的前面
- 使用 char 分隔符解析C++中的字符串,但将可重复的字符保留为每个解析的子字符串 (C++ STL) 中的分隔符
- 局部变量保留函数中的值
- 为什么共享_ptr需要保留foref_ptr的参考计数
- 保留对tbb :: concurrent_unordered_map项目的参考安全吗?
- 在C 中进行可选参考,保留对象寿命
- 变量作为参考不保留