Изменения аргумента c ++ в функции потока - PullRequest
0 голосов
/ 30 октября 2019

Я пишу приложение для Android, которое читает текстовый файл на языке C ++ (NDK).

Я копирую файл list из папки assets в /data/user/0/my-package/files/list, где я могу читать с роднымкод, после завершения копирования или, если файл назначения существует, я делаю следующее:

const char* fileName = env->GetStringUTFChars(_name, nullptr);
const char* filePath = env->GetStringUTFChars(_destination, nullptr);
if(copy_file(AAssetManager_fromJava(env, manager),fileName, filePath)){
    Reader *r = new Reader();
    log("Initializing reader with file: %s",filePath);
    thread t(&Reader::read, r, filePath);
    t.detach();// will crash if no detach, join() will block the UI thread.
}

И мой Reader::read:

void Reader::read(const char* filePath){
    log("Reading from file: %s",filePath);
    ifstream infile(filePath);
    string line;
    while(infile>>line){
        // read logic ...
    }
}

Я получаю другой вывод, некоторыераз

Initializing reader with file: /data/user/0/my-package/files/list
Reading from file: /data/user/0/my-package/files/list

и все работает как положено. Но иногда я получаю

Initializing reader with file: /data/user/0/my-package/files/list
Reading from file: /data/user/0/my-package/files

Видите? Кажется, путь к файлу как-то обрезается, и мой ifstream пытается прочитать каталог files.

Мне сказали, что аргумент filePath будет передан в поток по умолчаниюи нет другого потока, работающего с переменной, единственное, что происходит с filePath после инициализации потока, это:

  env->ReleaseStringUTFChars(_destination, filePath);

Я пробовал много разных способов передать путь к файлу в новый поток,если я передам filePath как std::ref(filePath), я получу пустую строку в функции read, потому что переменная уже очищена снаружи.

Есть какие-либо предложения по этому поводу?

1 Ответ

1 голос
/ 30 октября 2019

Вызов ReleaseStringUTFChars до завершения потока будет иметь катастрофические последствия, так как память, на которую указывает filePath , также будет освобождена. Если вы не до конца понимаете, как работают указатели и обработка памяти, я предлагаю использовать что-то вроде std :: string вместо const char * и передать эту строку в вашу функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...