从方法传出后返回指针值更改

时间:2017-03-07 07:16:24

标签: c++ pointers eigen

使用Eigen库时,我对以下代码有一种奇怪的行为。

如果我将指针分配给DoubleListCg->doubles,那么我为DoubleListCg->doubles[i]得到的值是错误的。但是如果我逐个分配元素,那么上面指针数组得到的值是正确的。为什么呢?

这是我的代码:

#define DllExport   __declspec( dllexport ) 

#include "stdafx.h"
#define EIGEN_USE_MKL_ALL
#include <iostream>
#include "Eigen/Dense"
#include "Eigen/src/Core/util/MKL_support.h"
#include <Eigen/Sparse>
#include <Eigen/Eigenvalues>
#include <vector>
#include <Eigen/PardisoSupport>
using namespace std;
using namespace Eigen;

extern "C" struct DllExport DoubleListCg
{
    int num_points;
    double* doubles;
};

// working
void DoubleList(VectorXd vector, DoubleListCg *dListPtr)
{
    dListPtr->num_points = vector.size();
   dListPtr->doubles= (double*) malloc ( dListPtr->num_points*sizeof(double));
   for (int i = 0; i < vector.size(); i++)
   {
       dListPtr->doubles[i]=vector[i];
   }     

}

//not working
void DoubleList2(VectorXd vector, DoubleListCg *dList)
{
    dList->num_points = vector.size();
    dList->doubles =vector.data();

}

void VectorConvert()
{
    VectorXd vector(3);
    vector<<1,2,3;

    DoubleListCg dList;
    DoubleList(vector, &dList);  //this works; the dList gets the right values at first element

    DoubleListCg dList2;
    DoubleList2(vector, &dList2)  //this doesn't work; the dList2 gets the wrong values at first element


}

我挂断电话一定是非常基本的东西。

相关问题:无论如何,我可以在dList->doubles指出vector.data()吗?我不想一遍又一遍地复制所有内容

2 个答案:

答案 0 :(得分:3)

void DoubleList(VectorXd vector, DoubleListCg *dListPtr) vector中是参数的(临时)副本。分配内存然后将值复制到其中时,它们将保留在dListPtr中。在不工作的情况下,.data()指针指向临时分配的数组。当它超出范围时,不保证内存保持分配状态。如果您通过引用传递vector,则内存将保持分配状态,直到原始范围超出范围。

答案 1 :(得分:3)

//not working
void DoubleList2(VectorXd vector, DoubleListCg *dList)
{
    dList->num_points = vector.size();
    dList->doubles =vector.data();
}

在上面的函数中,vector是函数DoubleList2的局部变量。当函数返回或完成时,此局部变量将被销毁,dList->doubles成为悬空指针,如果访问此类悬空指针,则会导致未定义行为。

正确的实施将是:

void DoubleList2(VectorXd vector, DoubleListCg *dList)
{
    dList->num_points = vector.size();
    dList->doubles = (double*) malloc ( dList->num_points*sizeof(double));
    memcpy(dList->doubles, vector.data(), dList->num_points*sizeof(double));
}