0

I have a problem initializing one simple char array. ( With values of 0's ) The size of the char array is higher and/or equal to 2Mb. I already searched the internet and read everything I could find (from What is the maximum size of buffers memcpy/memset etc. can handle? to ... I don't know) and tried many different processes ( from trying to append values into the char array to trying to ... ). The purpose of this code is to write into a file using C library ( NDK ). The snipper that is being shown below works fine if I try to write values equal or lower then 1Mb. Please help me with suggestions that could replace "memset". Here is a sample code:

My c library:

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <linux/errno.h>
#include <errno.h>
#include <fcntl.h>


#define APPNAME "AppLogger2"

#define  ALOG(...)  __android_log_print(ANDROID_LOG_INFO,APPNAME,__VA_ARGS__)

int fd_is_valid(int fd) {
    return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}


extern "C"
JNIEXPORT jboolean


JNICALL
Java_project_vasile_emanuel_gresanu_overwrite_1intrnal_1externals_1storage_utils_my_threads_WiperWorkerImpl_executeWiping(
        JNIEnv *env, jclass clazz, jint fd, jlong bufferSize, jint patterntoWrite = 0) {

    char str[80];
    sprintf(str, "FileDescriptor Primit = %d", fd);
    ALOG(str, __LINE__);

    if (fd_is_valid(fd)) {
        char buf[bufferSize];//allocate buffer
        memset(buf, patterntoWrite, (size_t) bufferSize);// init buffer

        while (true) {
            if (0 < write(fd, buf, (size_t) bufferSize)) {// write to file
                if (0 > fsync(fd)) //write to the raw disk
                {
                    ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
                    break;
                }
            } else {
                ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
                break;
            }
        }
        return JNI_TRUE;
    } else {
        ALOG("Sunt probleme cu file descriptorul primit!", __LINE__);
    }

    return JNI_FALSE;
}

Thre Java code:

class WiperWorkerImpl(val pathToFile: DocumentFile, ...): Runnable{

    companion object {

        const val useCExternalFunctionToOverWriteSpace = true

        // Used to load the 'native-lib' library on application startup.
        init {
            System.loadLibrary("native-lib")
        }
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    external fun executeWiping(fileDescriptorValue: Int, bytesToWrite:Long, patternToUse:Int): Boolean


override fun run() {
val pfd: ParcelFileDescriptor = contentResolver.openFileDescriptor(pathToFile.uri, "w")
                        if(checkTheRamSpaceForTheBytestThatAreGoingToBeWritten(bytesPerBlockToWriteLocalThread.get())) {
                            if (executeWiping(pfd.fd, bytesPerBlockToWriteLocalThread.get(), 0)) {
                                AppLogger.i("WiperWorkerImpl. Finish with success")
                            } else {
                                AppLogger.e("WiperWorkerImpl. Finished with error!")
                            }
                        }
                        closeFileDescriptor(pfd)
}

}

The error: enter image description here

  • 2
    Typically problems like this stem from some kind of stack limit in the environment, but the exception you get doesn't sound like that. Anyway, no reason to use an automatic variable for this, try heap-allocating it instead using `calloc()` or move it to file scope. – unwind Mar 21 '18 at 09:08

1 Answers1

1

Thanks unwind, you saved me. Now it works fine. Here is the correct code:

JNICALL
Java_project_vasile_emanuel_gresanu_overwrite_1intrnal_1externals_1storage_utils_my_threads_WiperWorkerImpl_executeWiping(
        JNIEnv *env, jclass clazz, jint fd, jlong bufferSize, jint patterntoWrite = 0) {

    char str[80];
    sprintf(str, "FileDescriptor Primit = %d", fd);
    ALOG(str, __LINE__);

    if (fd_is_valid(fd)) {

        char *buf = (char*) calloc(bufferSize, sizeof(char));//allocate buffer. Now it doesn't matter how big is the buffer
        for(int i=0;i<bufferSize;i++)
        {
            buf[i] = 0;
        }

        while (true) {
            if (0 < write(fd, buf, (size_t) bufferSize)) {// write to file
                if (0 > fsync(fd)) //write to the raw disk
                {
                    ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
                    break;
                }
            } else {
                ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
                break;
            }
        }
        return JNI_TRUE;
    } else {
        ALOG("Sunt probleme cu file descriptorul primit!", __LINE__);
    }

    return JNI_FALSE;
}