У меня была эта проблема, которая сводит меня с ума. У меня есть класс 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. Но каким-то образом местоположение памяти больше не является действительным.
Со времени вчерашнего утра меня это беспокоило, и я не смог ее разрешить и занялся другими делами, но мне все еще нужно решить ее в ближайшее будущее.
Кто-нибудь знает, почему это может происходить? Здесь нет многопоточности, больше нет: все это однопоточное.