所以我读了这个帖子和其他许多人: Function does not change passed pointer C++
但我还是无法解决我的问题。 我有一个声明如下的函数:
'use strict';
var Users = require('mongoose').model('Users');
module.exports = {
getAll: function() {
return Users.find({}, function(err, data) {
if (err) {
console.log(err);
}
console.log(data); // [ [ object Object ] ]
return data;
});
},
}
Wich工作,打印很好,我的意思是:listNodes变量有3个元素,全部是5个。但是,当此函数返回时,不会更新值。通过这个,我的意思是变量有垃圾。我把这个函数称为另一个这样的函数:
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 << ",";
}
}
同样,在这个函数中,cout将输出内存垃圾而不是输出3个五。 关于如何进行的任何想法,当功能测试返回时,我已填充列表?
答案 0 :(得分:1)
我相信你正在考虑的问题(与此代码中的其他问题相反)实际上并不是你在想什么。列表保持其值,问题是它具有的值指向垃圾内存。
执行此操作时:
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 ++方面不是很好,但是,你通常不想处理原始指针,但它说明了我认为你正在努力的观点。
答案 1 :(得分:0)
在此代码中,
void create(list<int*> listNodes){
listNodes=teste(&listNodes);
...正式参数listNodes
按值传递。这意味着该函数接收在调用siste中作为实际参数传递的任何内容的副本。对此副本的更改不会反映在实际参数中。
拨打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){
...最好是一个传递引用的参数。指针可以为null。这对于这个函数没有意义,代码也没有准备好处理它。
接下来,在
中 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(n 2 )复杂性,即执行时间。
只需迭代迭代器即可。这是迭代器的用途。迭代。
总结一下,你看到的垃圾是由于未定义的行为造成的。
只是,不要这样做。