Я пишу класс изображения для проекта, используя необработанные данные из stb_image. В деструкторе этого класса я освобождаю указатель на данные изображения, чтобы избежать утечек памяти. Однако, когда вызывается деструктор и данные освобождаются, я получаю нарушение прав доступа.
Заголовок изображения:
class Image {
unsigned char* pixelData;
public:
int nCols, nRows, nChannels;
Image(const char* filepath);
Image(unsigned char* data, int nCols, int nRows, int nChannels);
Image();
~Image();
Image getBlock(int startX, int startY, int blockSize);
std::vector<unsigned char> getPixel(int x, int y);
void writeImage(const char* filepath);
};
Конструктор и деструктор изображения:
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image.h"
#include "stb_image_write.h"
#include "image.hpp"
Image::Image(const char* filepath) {
pixelData = stbi_load(filepath, &nCols, &nRows, &nChannels, 0);
assert(nCols > 0 && nRows > 0 && nChannels > 0);
std::cout << "Image width: " << nCols << "\nImage height: " << nRows << "\nNumber of channels: " << nChannels << "\n";
}
Image::~Image() {
stbi_image_free(this->pixelData);
}
Минимальный воспроизводимый пример:
int main() {
Image image;
image = Image("./textures/fire.jpg");
}
Также поставьте точку останова в деструкторе. Не удивляйтесь, если он будет вызываться несколько раз, где каждый раз pixelData
будет одним и тем же значением указателя. Если это произойдет, то я склонен закрыть этот вопрос как дубликат правила 3-х ссылок.
Я попытался поставить точку останова, как вы сказали, и она вызывалась несколько раз с одним и тем же значением указателя, так что, вероятно, это так.
изображение = изображение("./текстуры/огонь.jpg"); Это назначение копирования из временного (xvalue). Таким образом, он сначала создает объект и передает указатель pixelData экземпляру изображения. Но сразу после этой строки pixelData освобождается, потому что временный объект уничтожается. Итак, в конце концов, внутри экземпляра изображения уже есть освобожденный указатель.
Конструктор копирования по умолчанию приведет к двойному освобождению. Есть два способа исправить это -
Ваш класс
Image
нельзя безопасно скопировать или назначить. Пожалуйста, опубликуйте минимальный воспроизводимый пример , который показывает, как вы используете этот класс. Напримерint main() { Image im("somefile");; ... Image im2 = im; }
-- Вот этот код вызовет проблемы. Прочтите правило 3 и перейдите в раздел «Управление ресурсами» по этой ссылке.