我正在尝试在 C++ 上构建一个基本的图像处理项目。我完成了源代码的实现。然后我用 valgrind 检查内存泄漏。有6处内存泄漏,我在下面分享。我一直试图找出导致泄漏的原因,但我找不到。我分享了valgrind引用的相关方法。
==5580== 51,373 bytes in 287 blocks are definitely lost in loss record 7 of 7
==5580== at 0x484A2F3: operator new[](unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==5580== by 0x10C382: Image::copy_column_to_buffer(unsigned char const*, int) (Image.cpp:82)
==5580== by 0x10C6A5: Image::smooth_y(float, int) (Image.cpp:131)
==5580== by 0x10C7BD: Image::smooth(float, int, float, int) (Image.cpp:146)
==5580== by 0x10EA84: main (main.cpp:13)
void Image::smooth(float sigma_x, int n_x, float sigma_y, int n_y)
{
smooth_x(sigma_x, n_x);
smooth_y(sigma_y, n_y);
}
void Image::smooth_x(float sigma, int n)
{
float* gaussian_kernel = create_gaussian_kernel(sigma, n);
uchar* row;
uchar* buffer;
for (int y = 0; y < height(); y++) {
row = data(y);
buffer = copy_row_to_buffer(row, n);
smooth_buffer(buffer, gaussian_kernel, width(), n);
memcpy(row, buffer, width() * sizeof(*row));
}
delete[] buffer;
delete[] gaussian_kernel;
}
void Image::smooth_y(float sigma, int n)
{
float* gaussian_kernel = create_gaussian_kernel(sigma, n);
uchar* column;
uchar* buffer;
for (int x = 0; x < width(); x++) {
column = data() + x;
buffer = copy_column_to_buffer(column, n);
smooth_buffer(buffer, gaussian_kernel, height(), n);
for (int y = 0; y < height(); y++) {
column[y * width()] = buffer[y];
}
}
delete[] buffer;
delete[] gaussian_kernel;
}
float* Image::create_gaussian_kernel(float sigma, int n)
{
if(sigma < 0) throw invalid_argument("Sigma value must be non-negative! Provided:" + to_string(sigma));
if(n > m_width / 2) throw invalid_argument("n value cannot be exceed half of the image which is:" + to_string(m_width / 2) + " Provided:" + to_string(n));
int size = 2 * n + 1;
float* gaussian_kernel = new float[size];
double sum = 0;
for (int i = 0; i < size; i++) {
int x = i - n;
gaussian_kernel[i] = exp(-(pow(x,2) / (2 * pow(sigma, 2))));
sum += gaussian_kernel[i];
}
for (int i = 0; i < size; i++) {
gaussian_kernel[i] /= sum;
}
return gaussian_kernel;
}
uchar* Image::copy_row_to_buffer(const uchar* row, int border_size)
{
uchar* buffer = new uchar[width() + 2 * border_size];
memcpy(buffer + border_size, row, sizeof(*row) * width());
for (int x = 0; x < border_size; x++) {
buffer[x] = buffer[2 * border_size - x];
buffer[width() + 2 * border_size - 1 - x] = buffer[width() - 1 + x];
}
return buffer;
}
uchar* Image::copy_column_to_buffer(const uchar* column, int border_size)
{
uchar* buffer = new uchar[height() + 2 * border_size];
for (int y = 0; y < height(); y++) {
buffer[y + border_size] = column[y * width()];
}
for (int y = 0; y < border_size; y++) {
buffer[y] = buffer[2 * border_size - y];
buffer[width() + 2 * border_size - 1 - y] = buffer[width() - 1 + y];
}
return buffer;
}
您似乎没有正确释放 Image 类的 smooth_x 和 smooth_y 方法中的内存。发生泄漏是因为您在这两个方法中为缓冲区数组分配内存并在每个方法结束时删除它,但没有为循环的每次迭代释放内存。
要修复内存泄漏,您应该在循环内每次迭代结束时删除缓冲区数组。
void Image::smooth_x(float sigma, int n)
{
float* gaussian_kernel = create_gaussian_kernel(sigma, n);
uchar* row;
for (int y = 0; y < height(); y++) {
row = data(y);
uchar* buffer = copy_row_to_buffer(row, n);
smooth_buffer(buffer, gaussian_kernel, width(), n);
memcpy(row, buffer, width() * sizeof(*row));
delete[] buffer; // Delete the buffer for each row
}
delete[] gaussian_kernel;
}
void Image::smooth_y(float sigma, int n)
{
float* gaussian_kernel = create_gaussian_kernel(sigma, n);
uchar* column;
for (int x = 0; x < width(); x++) {
column = data() + x;
uchar* buffer = copy_column_to_buffer(column, n);
smooth_buffer(buffer, gaussian_kernel, height(), n);
for (int y = 0; y < height(); y++) {
column[y * width()] = buffer[y];
}
delete[] buffer; // Delete the buffer for each column
}
delete[] gaussian_kernel;
}
如果这不是问题,我们可能需要完整的源代码