2017-03-07 2 views
-1

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->doublesvector.data()에 있습니까? 나는 모든 것을 반복해서 복사하고 싶지 않다.

+0

왜이 질문을 downvoted와 (-재현하지 않는 이유) 폐쇄 선정됐다? – Graviton

답변

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

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)); 
} 
+0

어쨌든'vector.data()'에서'dList-> double '을 가리킬 수 있습니까? 반복적으로 모든 것을 복사하고 싶지 않습니다. – Graviton

+0

@Avi Ginsburg에서 제안한대로 벡터를 참조로 사용하십시오. 벡터의 수명은 p에서 유효합니다. 'dList-> doubles '에 접근하는 레이스. – sameerkn

+0

올바른 구현이'vector.data()'에서'dList-> doubles'까지의 모든 데이터 사본이 아닙니까? – Graviton

3

void DoubleList(VectorXd vector, DoubleListCg *dListPtr)vector은 인수의 (임시) 복사본이다. 메모리를 할당 한 다음 값을 복사하면 dListPtr에 유지됩니다. 작동하지 않는 경우 .data() 포인터가 임시 할당 된 배열을 가리 킵니다. 범위를 벗어나면 메모리는 할당 된 상태로 유지되지 않습니다. 참조로 vector을 전달하면 원본은 범위를 벗어날 때까지 메모리가 할당 된 상태로 유지됩니다. 상기 함수에서 vector

+0

알겠습니다. 어쨌든 vector.data()에서'dList-> double '을 직접 가리킬 수 있습니까? – Graviton

+0

(DoubleList (VectorXd & vector ...)) 참고로 전달할 수 있습니다. 표현식을 DoubleList에 전달하면 작동하지 않습니다. 즉 'DoubleList (3.0 * vec ...)'. –

+0

'DoubleList'에 표현식을 전달한다는 것은 무엇을 의미합니까? – Graviton

관련 문제