1

I have a c function int* GenerateIntArray()

it will generate a int array like [0,8,28,108,0,3] and return by Int*

int* GenerateIntArray(){ 
int rtn[6]={0,8,28,108,0,3};
return rtn;
}

in my jni layer : fun getIntArrayFromJNI:JIntArray

I do this for get Int* from C Lib

jintArray rtn = env->NewIntArray(6);
int *temp = C_GetINTArrayData();
env->SetIntArrayRegion(rtn, 0, 6, temp);
return rtn; 

and convert it to IntArray

but in Android Layer: fun getIntArrInAndroid():IntArray

var result=getIntArrayFromJNI()

I check the data list it show [-214587424,119,0,0,205189680,-1275068295]

is somewhere wrong to convert Int array?

Botje
  • 26,269
  • 3
  • 31
  • 41
NeilLin
  • 195
  • 3
  • 11
  • Please don't tag multiple languages, especially if one of them isn't relevant. You either program in C, or in the totally different language C++, not both at the same time. – Some programmer dude May 17 '22 at 08:57
  • sorry, I don't know it is wrong in c convet to C++ or C++ convert to kotlin, so I tag they all – NeilLin May 17 '22 at 09:16
  • Most likely your problem is located in `C_GetINTArrayData` (which is not included in your question). Better try first to start with a constant int array as shown here: https://nachtimwald.com/2017/07/09/jni-is-not-your-friend/#arrays BTW: if `C_GetINTArrayData` allocates the array dynamically with malloc then you have a memory leak as you never free the memory in `temp`. – Robert May 17 '22 at 09:20
  • Is it intentional that `GenerateIntArray` returns a pointer to a local variable ? I don't understand the purpose of your program, but I think you'd better to return a global static variable instead. –  May 17 '22 at 09:47
  • In fact, GenerateIntArray() is a algorithm function and return Int array,my issue is int array didn't return right to android layer, so I made it simple to description,I can't make it global parameter because it's jdk project, it need C->C++->kotlin – NeilLin May 17 '22 at 10:15
  • C cannot "return an int array". You need to return a pointer to a heap-allocated array that will survive the function call, as others have said. Please edit your question with a more representative sample, because return the address of a local array is undefined behavior in C and currently the cause of all your problems. – Botje May 17 '22 at 10:51
  • I even suggest that `GenerateIntArray` returns nothing, or maybe a simple boolean validation value, but takes as parameter a valid pointer to a buffer to be filled. –  May 17 '22 at 10:56

2 Answers2

0

Since your problem seem to coming from your GenerateIntArray function, returning a pointer to local variable (which is not a good idea at all), I suggest you rewrite the function in more suitable way:

void GenerateIntArray(int *buffer, size_t size) 
{
   for(size_t i = 0; i < size; ++i) 
     // do something with your buffer...
}

You then should call the GenerateIntArray with a valid pointer like this :

int array[256];

GenerateIntArray(array, 256);

or using dynamically allocated buffer, like that :

int* buffer = (int*)malloc(256 * sizeof(int));

GenerateIntArray(buffer, 256);

Alternatively, in C++ fashion using vector standard container as suggested by @Michael in comments :

void GenerateIntArray(std::vector<int>& array) 
{
   // do something with your array...
}

With the following usage:

std::vector<int> my_array;

GenerateIntArray(my_array);
  • Based on how the JNI calls are performed in OP's example code, they are in fact programming in C++, not in C. So there should be no need for things like `malloc` (i.e. a `std::vector` would be a better alternative). – Michael May 17 '22 at 11:10
  • Note that it is perfectly safe to return a `std::vector` from a function; the compiler will make sure the returned value is a valid container. – Botje May 17 '22 at 13:14
  • @Botje agree, but this would force copy objects, which is, IMHO to avoid as much as possible. –  May 17 '22 at 13:25
  • This pattern is so common that compilers have [a special optimization for it](https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization), which avoids the copy. – Botje May 18 '22 at 12:02
0

When you want to do that in this way, you can change your void GenerateIntArray() code to:

int* GenerateIntArray()
{ 
  static int rtn[6]={0,8,28,108,0,3};
  return rtn;
}

Because, the int array is allocated on the stack and will be disappear when the function returns.

AD1170
  • 378
  • 1
  • 9