Массив строк в стиле C сначала допустим, затем не читается - PullRequest
0 голосов
/ 15 апреля 2020

У меня была эта проблема, которая сводит меня с ума. У меня есть класс ImageLoader, который с некоторыми именами файлов будет загружать изображения с помощью библиотеки, которую я нашел в Интернете, для быстрой обработки файлов TIFF. Библиотека здесь не важна, как и фактическая загрузка изображений.

Проблема заключается в хранении и извлечении имен файлов. Вот самый простой пример, содержащий root моей проблемы:

class ImageLoader {
  public:
    void askUserFiles();
    void loadImages();
  private:
    char** filenamesToLoad; //< Array of C-style strings for filenames
    std::size_t nbImages; //! Number of images, initialized at 0 and set after user choice
};

void ImageLoader::askUserFiles() {
  // Ask the user for files ...
  this->filenamesToLoad = static_cast<char**>(calloc(numberOfuserFiles, sizeof(char*)));
  this->nbImages = numberOfuserFiles;
  // Copy data inside :
  for (std::size_t i = 0; i < this->nbImages; ++i) {
    this->filenamesToLoad[i] = strdup(userFiles[i].c_str());
  }
}

void ImageLoader::loadImages() {
  std::cerr << "Filenames (" << this->nbImages << ") : " << '\n';
  for (std::size_t i = 0; i < this->nbImages; ++i) {
    // Here, printing filenames DOESN'T cause a segfault :
    std::cerr << '\t' << this->filenamesToLoad[i] << '\n';
  }

  // Even in my code, there is nothing here : I print the filenames and process them directly after

  std::size_t currentItem = 0;
  while (currentItem < this->nbImages) {
    // Here, printing filenames DOES cause a segfault, and only when currentItem > 0 :
    std::cerr << '\t' << this->filenamesToLoad[currentItem] << '\n';
    // (It works for the first item in the array, but not the rest)

    // The program doesn't even get this far :
    LibraryFileHandle* f = LibraryOpenFile(this->filenamesToLoad[currentItem]);
    // Note : the LibraryOpenFile takes a const char* as argument, and I'm giving it a char*
    currentItem++;
  }
}

Второй l oop (while) здесь, потому что сначала этот код был кодом для рабочего потока, предполагается загружать изображения (так как мне нужно загрузить много из них одновременно). Но теперь я делаю это последовательно, на одном ядре только для определения root причины проблемы.

Я определил, что это не проблема из-за currentItem, она всегда находится в пределах Границы [0, nbImages [и даже сегменты памяти одинаковы! Если к filenamesToLoad[0] обращаются в 0xXXXXXXXXe640 в первый раз для l oop, к нему все равно будут обращаться в 0xXXXXXXXXe640 в то время как l oop. Но каким-то образом местоположение памяти больше не является действительным.

Со времени вчерашнего утра меня это беспокоило, и я не смог ее разрешить и занялся другими делами, но мне все еще нужно решить ее в ближайшее будущее.

Кто-нибудь знает, почему это может происходить? Здесь нет многопоточности, больше нет: все это однопоточное.

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