变量作为参考不停留

时间:2016-09-18 00:54:00

标签: c++ variables reference

所以我读了这个帖子和其他许多人: 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个五。 关于如何进行的任何想法,当功能测试返回时,我已填充列表?

2 个答案:

答案 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元素指向的值时,该变量已超出范围并被其他东西使用,因此垃圾。

以下是两种可能的解决方案:

  1. 使用list<int>代替list<int *>。如果你想要做的就是存储一个整数列表,这就是你要走的路。
  2. 另一方面,如果你真的需要存储指向那些整数的指针,你需要从堆中分配内存:

    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
    
  3. 这在现代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 )复杂性,即执行时间。

只需迭代迭代器即可。这是迭代器的用途。迭代。

总结一下,你看到的垃圾是由于未定义的行为造成的。

只是,不要这样做。

相关问题