I am working on an android app using JNI.
I keep sending byte[]
from java and it arrives as a jbyteArray
in cpp.
To get from the jbyteArray
to a signed char*
i use this function:
jbyte* content_array = (env)->GetByteArrayElements(array,NULL);
(jbyte*
is just a typedef of signed char*
)
Now i did run into problems when trying to access the data at the signed char*
pointer at later times.
It think at some point the java garbage collector kicks in and frees the memory, so i can no longer access it.
To work around this issue, i am now copying the incoming data like this:
// newJavaByteData is the signed char* coming in from java
signed char* buffer = new signed char[length];
memcpy(buffer, newJavaByteData, length);
//javaByteData is a std::vector<signed char*>
javaByteData.push_back(buffer);
So far so good. At later frames i can read the data and when i do not need it any more, i delete it like this:
int frame_cnt=0;
while(frame_cnt<javaByteData.size()){
delete javaByteData[frame_cnt++];
}
javaByteData.clear();
Now i need to extract chunks of bytes from this data.
Again i am using memcpy
to extract the needed portion of the bytes.
This time i need to apply a offset to the source-pointer
char* extractedBytes[lengthOfBytes];
//originalJavaData is the signed char* i did alloc and memcpy into earlier
memcpy(extractedBytes, &originalJavaData[offset], lengthOfBytes* sizeof(char));
This is working well, until its not :(
I can extract data this way, but when the amount of bytes i extract exceed some limit, i am getting this error:
SIGSEGV (signal SIGSEGV: invalid address (fault address: 0x53))
The fault address varies with each time i run the app message.
I am not yet sure what the limit is, but i can extract 262144 bytes (256x256x4) just fine, while extracting 1048576 bytes (1024x1024x4) is causing the crash / signal.
I was thinking the issue was that i am running out of memory in the cpp thread, but i can happily alloc more memory. just the memcpy
is failing.
I think i could set up a eventHandler for the SIGSEGV signals, but i have no experience with that, and also i already tracked the issue down to the usage of memcpy
, so i hope it just a thing i am doing wrong with memcpy.
I am thinking that maybe its a problem with memory not aligned correctly and thus the memcpy
is failing due to the fact that i add the offset to the source-pointer.
Any help would be greatly appreciated.
OK. I found the problem.
It seem that i was running out of stack memory, while when i use heap memory i am good to go.
So instead of this lines:
char* extractedBytes[lengthOfBytes];
//originalJavaData is the signed char* i did alloc and memcpy into earlier
memcpy(extractedBytes, &originalJavaData[offset], lengthOfBytes* sizeof(char));
i now have this:
char* extractedBytes = new char[lengthOfBytes];
//originalJavaData is the signed char* i did alloc and memcpy into earlier
memcpy(extractedBytes, &originalJavaData[offset], lengthOfBytes* sizeof(char));
memcpy
is now doing its job and extracts portions of the signed char*
without complaining.
Of course by allocating the memory on the heap, i now have to take care of disposing my data later.
On a sidenote: I stopped copying the incoming data myself, and instead of GetByteArrayElements
i am now using GetByteArrayRegion
which is doing the copying for me.
Hope i do not get downvoted for answering my own question again. For me this is a valid solution to my problem.