相同循环和数组中的隔离错误
Segfault in Identical Loops and Arrays
因此,我以完全相同的方式声明两个 2D 浮点数组。
float** a1 = new float*[chunk_size];
for (i = 0; i < chunk_size; ++i) {
a1[i] = new float[chunk_size];
}
float** a2 = new float*[chunk_size];
for (i = 0; i < chunk_size; ++i) {
a2[i] = new float[chunk_size];
}
然后继续访问第一个,然后是第二个...
for (i = 0; i < chunk_size; ++i) {
for (j = n = m = d = 0; j < chunk_size; j = m) {
do {
std::cout << "i: " << i << " m: " << m << std::endl;
d = a1[i][m]; <-----------NO-SEGFAULT
++m;
} while (d != 0 && m < chunk_size);
delta = (d - a1[i][j]) / m;
n = j + 1;
while (n < j + m) {
a1[i][n] = a1[i][n - 1] + delta;
++n;
}
}
}
在第二个循环集上,我在第一次迭代中得到一个段错误。
for (j = 0; j < chunk_size; ++j) {
for (i = n = m = d = 0; i < chunk_size; i = m) {
do {
std::cout << "m: " << m << " j: " << j << std::endl;
d = a2[m][j]; <--------------SEGFAULT
++m;
} while (d != 0 && m < chunk_size);
delta = (d - a2[i][j]) / m;
n = i + 1;
while (n < i + m) {
a2[n][j] = a2[n - 1][j] + delta;
++n;
}
}
}
除非我错过了什么,或者没有分享其他重要的东西,否则我看不出是什么原因导致一个而不是另一个。
作为参考,i、j、n、m 和 chunk_size 属于 size_t
型,而 delta 和 d 属于 float
型。
编辑:控制台输出
i: 255 m: 248
i: 255 m: 249
i: 255 m: 250
i: 255 m: 251
i: 255 m: 252
i: 255 m: 253
i: 255 m: 254
i: 255 m: 255
m: 0 j: 0
Segmentation fault
瓦尔格林德乌普特
i: 255 m: 250
i: 255 m: 251
i: 255 m: 252
i: 255 m: 253
i: 255 m: 254
i: 255 m: 255
m: 0 j: 0
==3518== Use of uninitialised value of size 8 ==3518== at 0x403240: WSUMap::blockTypeIDAt(unsigned int, unsigned int, unsigned int) const (WSUMap.h:196)
==3518== by 0x402B54: WSUMap::WSUMap() (WSUMap.h:110)
==3518== by 0x4017CB: __static_initialization_and_destruction_0(int, int) (main.cpp:8)
==3518== by 0x4017E0: _GLOBAL__sub_I_map (main.cpp:20)
==3518== by 0x403DFC: __libc_csu_init (in /home/will/Dev/a.out)
==3518== by 0x5A2AE3F: (below main) (libc-start.c:203)
==3518==
==3518== Invalid read of size 4
==3518== at 0x403240: WSUMap::blockTypeIDAt(unsigned int, unsigned int, unsigned int) const (WSUMap.h:196)
==3518== by 0x402B54: WSUMap::WSUMap() (WSUMap.h:110)
==3518== by 0x4017CB: __static_initialization_and_destruction_0(int, int) (main.cpp:8)
==3518== by 0x4017E0: _GLOBAL__sub_I_map (main.cpp:20)
==3518== by 0x403DFC: __libc_csu_init (in /home/will/Dev/a.out)
==3518== by 0x5A2AE3F: (below main) (libc-start.c:203)
==3518== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==3518==
==3518==
==3518== Process terminating with default action of signal 11 (SIGSEGV)
==3518== Access not within mapped region at address 0x0
==3518== at 0x403240: WSUMap::blockTypeIDAt(unsigned int, unsigned int, unsigned int) const (WSUMap.h:196)
==3518== by 0x402B54: WSUMap::WSUMap() (WSUMap.h:110)
==3518== by 0x4017CB: __static_initialization_and_destruction_0(int, int) (main.cpp:8)
==3518== by 0x4017E0: _GLOBAL__sub_I_map (main.cpp:20)
==3518== by 0x403DFC: __libc_csu_init (in /home/will/Dev/a.out)
==3518== by 0x5A2AE3F: (below main) (libc-start.c:203)
==3518== If you believe this happened as a result of a stack
==3518== overflow in your program's main thread (unlikely but
==3518== possible), you can try to increase the size of the
==3518== main thread stack using the --main-stacksize= flag.
==3518== The main thread stack size used in this run was 8388608.
==3518==
==3518== HEAP SUMMARY:
==3518== in use at exit: 3,225,736 bytes in 1,803 blocks
==3518== total heap usage: 1,816 allocs, 13 frees, 3,279,401 bytes allocated
==3518==
==3518== 122,880 bytes in 120 blocks are definitely lost in loss record 9 of 13
==3518== at 0x4C28147: operator new[](unsigned long) (vg_replace_malloc.c:348)
==3518== by 0x402E7B: WSUMap::blockTypeIDAt(unsigned int, unsigned int, unsigned int) const (WSUMap.h:162)
==3518== by 0x402B54: WSUMap::WSUMap() (WSUMap.h:110)
==3518== by 0x4017CB: __static_initialization_and_destruction_0(int, int) (main.cpp:8)
==3518== by 0x4017E0: _GLOBAL__sub_I_map (main.cpp:20)
==3518== by 0x403DFC: __libc_csu_init (in /home/will/Dev/a.out)
==3518== by 0x5A2AE3F: (below main) (libc-start.c:203)
==3518==
==3518== LEAK SUMMARY:
==3518== definitely lost: 122,880 bytes in 120 blocks
==3518== indirectly lost: 0 bytes in 0 blocks
==3518== possibly lost: 0 bytes in 0 blocks
==3518== still reachable: 3,102,856 bytes in 1,683 blocks
==3518== suppressed: 0 bytes in 0 blocks
==3518== Reachable blocks (those to which a pointer was found) are not shown.
==3518== To see them, rerun with: --leak-check=full --show-reachable=yes
==3518==
==3518== For counts of detected and suppressed errors, rerun with: -v
==3518== Use --track-origins=yes to see where uninitialised values come from
==3518== ERROR SUMMARY: 1144833 errors from 7 contexts (suppressed: 4 from 4)
Segmentation fault
以下是变量...
size_t i, j, n, m, chunk_size, pixel_size, scale;
i = j = n = m = 0;
chunk_size = 256;
pixel_size = 4;
scale = chunk_size / pixel_size;
float delta, d;
这是数组声明...
for (i = 0; i < pixel_size; ++i) {
for (j = 0; j < pixel_size; ++j) {
(i == 0) ? n = i : n = (i * scale) - 1;
(j == 0) ? m = j : m = (j * scale) - 1;
a1[n][m] = pixels[i][j];
a2[n][m] = pixels[i][j];
}
}
for (i = n = m = d = 0; i < chunk_size; i = m) {
do {
std::cout << "m: " << m << " j: " << j << std::endl;
d = a2[m][j]; <--------------SEGFAULT
++m;
} while (d != 0 && m < chunk_size);
由于您使用的是do ... while()
语句,因此只有在第一次运行do while
循环后才会检查m < chunk_size
。因此,在第二次运行内部for
中,第一次运行do ... while
循环访问数组边界之外。
您可以将其更改为while(d != 0 && m < chunk_size) { ... }
或重写逻辑以确保在m >= chunk_size || j >= chunk_size
时不会访问a2[m][j]
。
在这一行中:
while (n < j + m) {
j+m
很容易变得大于块大小。如果您曾经在m
大于 chunk_size /2
时绕过第一个循环循环,就会发生这种情况。这将导致写入数组边界之外并导致未定义的行为。
如果chunk_size
是256,那么你在这里越界了:
while (n < j + m) {
a1[i][n] = a1[i][n - 1] + delta;
n
的值变为 256,这超出了范围。
下面是一个示例:http://ideone.com/fAUA8j
每当n
变为 256 时,就会打印"You're dead"
。
相关文章:
- 从矢量中删除元素后出现隔离错误
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- 线程时访问静态映射时出现隔离错误
- 并行快速排序分区中的隔离错误
- C++多线程程序:变量定义为类成员的隔离错误
- TFLite 隔离错误,通过获取C++输入和输出
- 我只是在寻找模板,在我的书中找到了这段代码,这显示了隔离错误?
- pthread_create中错误 4 的隔离错误
- 递归树遍历/分支删除的隔离错误
- 在类模板上使用 arm gcc 编译期间的隔离错误
- 从大量文件读取时出现隔离错误
- 在PHP扩展中使用emalloc从线程时出现隔离错误
- 通过 Boost Python 在C++对象之间传递共享指针的隔离错误
- 在QT中单击菜单时出现隔离错误
- 尝试访问标头声明成员时出现隔离错误
- 搜索链表时出现隔离错误
- 模板化子类析构函数中的隔离错误
- 插件中节点.js/Nan 回调C++不频繁的隔离错误
- 将行添加到 GTKTreeView 时的隔离错误
- 找不到命令时打开的隔离错误