C++ 3D 数组中的 Valgrind 错误
Valgrind error in C++ 3D array
我无法理解在编译 C++ 程序以创建和管理 3D 数组时显示的 Valgrind 错误。
我在我的 Mac 上编写了软件,一切看起来都很好,但是当我将它移植到 Ubuntu 时,我不仅遇到了 Valgrind 错误,而且输出也不同(而且是错误的)来自 Mac.
中的那个
这是 Valgrind 错误:
==10705== Invalid write of size 4
==10705== at 0x401095: Matrice3D<int>::Matrice3D(unsigned int, unsigned int, unsigned int, int const&) (in /media/psf/sharedFolder/Progetto_2/main.exe)
==10705== by 0x400BE1: main (in /media/psf/sharedFolder/Progetto_2/main.exe)
==10705== Address 0x5ab6e10 is 0 bytes after a block of size 192 alloc'd
==10705== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10705== by 0x40102E: Matrice3D<int>::Matrice3D(unsigned int, unsigned int, unsigned int, int const&) (in /media/psf/sharedFolder/Progetto_2/main.exe)
==10705== by 0x400BE1: main (in /media/psf/sharedFolder/Progetto_2/main.exe)
==10705==
--10705-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--10705-- si_code=1; Faulting address: 0x1105AB6E38; sp: 0x802ca9e30
和引用的构造函数:
Matrice3D(unsigned int height, unsigned int width, unsigned int depth, const T &value) : _3D_matrix(0), _height(0), _width(0), _depth(0) {
try {
_3D_matrix = new T[height * width * depth];
for (int z = 0; z < depth; z++) {
for (int j = 0; j < height; j++) {
for (int k = 0; k < width; k++) {
_3D_matrix[j * height * depth + k * depth + z] = value;
}
}
}
}
catch(...) {
delete[] _3D_matrix;
throw;
}
_height = height;
_width = width;
_depth = depth;
}
有人有过类似经历吗?难道我做错了什么?
提前致谢!
看起来写入问题是由于混淆了各种 for
级别的 ranges/indexing 引起的:
_3D_matrix[j * height * depth + k * depth + z] = value;
看看这里:https://ideone.com/gkUXib - 您的代码已移至一个独立函数中,并添加了索引输出。输出显示一些索引被分配了两次(即示例中的 22),一些索引从未分配给(如 63)。索引的顺序看起来很奇怪,很难推理。
可能宽度、高度和深度的某种组合会导致您已经注意到的错误。
我建议简化 fors 变量(使 "row" 表示一行,而不是其他),使用 std::array
或简单地使用单维数组并实现行、列和深入自己。
你的指数计算有误。
z
从 0
变为 depth
。
j
从 0
变为 height
。
k
从 0
变为 width
。
到目前为止一切顺利(好吧,j
和 k
而不是 x
和 y
是不寻常的,并且可能是造成混淆的很大一部分)。但是:
_3D_matrix[j * height * depth + k * depth + z] = value;
j
乘以height
是错误的,应该是width
.
考虑这种情况:j = height - 1
、k = 0
、z = 0
。那么您的索引将是 height * depth * (height - 1)
,如果 height
与 width
不同,这显然是不正确的。
调试不确定数组索引的情况的一个技巧是考虑极端情况。如果您考虑上述情况(或所有循环变量都是最大的情况),您会立即看到您的索引可以超过您的数组大小。
我无法理解在编译 C++ 程序以创建和管理 3D 数组时显示的 Valgrind 错误。
我在我的 Mac 上编写了软件,一切看起来都很好,但是当我将它移植到 Ubuntu 时,我不仅遇到了 Valgrind 错误,而且输出也不同(而且是错误的)来自 Mac.
中的那个这是 Valgrind 错误:
==10705== Invalid write of size 4
==10705== at 0x401095: Matrice3D<int>::Matrice3D(unsigned int, unsigned int, unsigned int, int const&) (in /media/psf/sharedFolder/Progetto_2/main.exe)
==10705== by 0x400BE1: main (in /media/psf/sharedFolder/Progetto_2/main.exe)
==10705== Address 0x5ab6e10 is 0 bytes after a block of size 192 alloc'd
==10705== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10705== by 0x40102E: Matrice3D<int>::Matrice3D(unsigned int, unsigned int, unsigned int, int const&) (in /media/psf/sharedFolder/Progetto_2/main.exe)
==10705== by 0x400BE1: main (in /media/psf/sharedFolder/Progetto_2/main.exe)
==10705==
--10705-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--10705-- si_code=1; Faulting address: 0x1105AB6E38; sp: 0x802ca9e30
和引用的构造函数:
Matrice3D(unsigned int height, unsigned int width, unsigned int depth, const T &value) : _3D_matrix(0), _height(0), _width(0), _depth(0) {
try {
_3D_matrix = new T[height * width * depth];
for (int z = 0; z < depth; z++) {
for (int j = 0; j < height; j++) {
for (int k = 0; k < width; k++) {
_3D_matrix[j * height * depth + k * depth + z] = value;
}
}
}
}
catch(...) {
delete[] _3D_matrix;
throw;
}
_height = height;
_width = width;
_depth = depth;
}
有人有过类似经历吗?难道我做错了什么? 提前致谢!
看起来写入问题是由于混淆了各种 for
级别的 ranges/indexing 引起的:
_3D_matrix[j * height * depth + k * depth + z] = value;
看看这里:https://ideone.com/gkUXib - 您的代码已移至一个独立函数中,并添加了索引输出。输出显示一些索引被分配了两次(即示例中的 22),一些索引从未分配给(如 63)。索引的顺序看起来很奇怪,很难推理。
可能宽度、高度和深度的某种组合会导致您已经注意到的错误。
我建议简化 fors 变量(使 "row" 表示一行,而不是其他),使用 std::array
或简单地使用单维数组并实现行、列和深入自己。
你的指数计算有误。
z
从 0
变为 depth
。
j
从 0
变为 height
。
k
从 0
变为 width
。
到目前为止一切顺利(好吧,j
和 k
而不是 x
和 y
是不寻常的,并且可能是造成混淆的很大一部分)。但是:
_3D_matrix[j * height * depth + k * depth + z] = value;
j
乘以height
是错误的,应该是width
.
考虑这种情况:j = height - 1
、k = 0
、z = 0
。那么您的索引将是 height * depth * (height - 1)
,如果 height
与 width
不同,这显然是不正确的。
调试不确定数组索引的情况的一个技巧是考虑极端情况。如果您考虑上述情况(或所有循环变量都是最大的情况),您会立即看到您的索引可以超过您的数组大小。