Search code examples
c++arraysfunctionpointersswig

lost value in array pointers among functions (compiled with swig to use in python3)


I don't understand why values get lost from func1 to func2 and then main. It prints ok in func1, but failed in func2 and main. I don't think it is a swig problem, more feels like a c++ code problem~ you can reproduce the problem with below code.

my test.cpp:

#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
#include <mutex>
#include "test.h"
void test::func1(float* feat) {
    std::vector<float> fv = {1,2,3,4,5,6,7};
    feat = fv.data();
    for (std::size_t i = 0; i < 7; ++i){
    std::cout <<  *feat << std::endl;
    feat++;
    }
}


bool test::func2(float* feat) {
    test::func1(feat);
}
bool test::main(float* feat){
    test::func2(feat);
    for (std::size_t i = 0; i < 7; ++i){
    std::cout <<  *feat << std::endl;
    feat++;
    }
}

my test.h:

#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
#include <mutex>

class test {
public:
    void func1(float* feat);
    bool func2(float* feat);
    bool main(float* feat);
};

my test.i:

%module test
%{
#define SWIG_FILE_WITH_INIT
#include "test.h"
%}

%include "carrays.i"
%array_functions(float, floatArray); 

%include <std_string.i>
%include "test.h"

when i test in python3:

>>> from test import test, new_floatArray, floatArray_getitem
>>> import numpy as np
>>> pp = test()
>>> temp = new_floatArray(5)
>>> pp.main(temp)
1
2
3
4
5
6
7
0
0
0
0
0
4.02252e-14
1.4013e-44
False

Solution

  • feat = fv.data();
    

    This line does not alter the data that feat points at, it changes which data the local version of feat points to.

    So when you return from func2(), neither feat nor the data it points to are changed. Since you pass unitialized data to main, you get the 7 prints from func 1 (from its own data), followed by 7 prints of uninitialized data, which is going to be whatever.

    I suspect you meant:

    memcpy(feat, fv.data(), fv.size() * sizeof(float));
    

    Which will copy the data from fv to the data feat points to.