【问题标题】:Why is this Segfault Occuring?为什么会发生此段错误?
【发布时间】:2015-04-21 22:46:59
【问题描述】:

所以我已经将段错误追溯到该行,但我不明白为什么这是段错误。有人可以详细说明我的方式的错误吗?

这里是变量声明。

size_t i, j, n, m, chunk_size, pixel_size;
i = j = n = m = 0;
chunk_size = 256;
pixel_size = 4;

这里是数组声明。

uint8_t** values = new uint8_t*[chunk_size];
for (i = 0; i < chunk_size; ++ i)
    values[i] = new uint8_t[chunk_size];

float** a1 = new float*[chunk_size];
for (i = 0; i < chunk_size; ++i)
    a1[i] = new float[chunk_size];

这就是发生段错误的地方。

float delta, d;

for (i = 0; i < 256; ++i) {
    for (j = n = m = d = 0; j < 256; j = m) {
        while (i == 0 || d != 0) {
            d = a1[i][m];    <------SEGFAULT per GDB
            ++m;
        }
        delta = (d - a1[i][j]) / m;
        n = j + 1;
        while (n < j + m) {
            a1[i][n] = a1[i][n - 1] + delta;
            ++n;
        }
    }
}

我对 C++ 还很陌生,无法弄清楚为什么这是一个段错误。这不是将变量值设置为数组中变量的正确方法吗?这是我的段错误的根源吗?

注意:整个事情的重点是使用我的简单插值公式将 4x4 数组扩展为 256x256 数组。

【问题讨论】:

  • 只要 m 大于或等于 chunk_size ,您就超出了数组的边界。这将是我对它的猜测。我还建议使用有意义的变量名,i、j、n、m 和 d 的描述性不是很强,而且更难弄清楚你要做什么。
  • 绝对确定i 和m 在调用d = a1[i][m]; 时在界内?
  • 您的 while 循环对m 超出范围没有安全性。
  • 对于i 和m 的哪些值,您得到了段错误?
  • 哇,谢谢大家的快速回复!我完全忽略了i 和它的界限。这仅适用于初始条件,所以一段时间后,m &lt; 256 的附加值似乎是补救措施。

标签: c++ arrays segmentation-fault interpolation


【解决方案1】:
while (i == 0 || d != 0) {
    d = a1[i][m];    <------SEGFAULT per GDB
    ++m;
}

这是一个无限的while 循环,在某些情况下(例如在外循环的第一次迭代中)。

【讨论】:

  • 一个递增数组索引的无限循环 => bang
【解决方案2】:

您的外部循环以i = 0 开头,内部循环以d = 0 开头,并且控制while 循环的逻辑不足(请参阅代码注释)。

for (i = 0; i < 256; ++i) {
    for (j = n = m = d = 0; j < 256; j = m) {
        // Here i == 0 is ALWAYS true (so d != 0 is ignored due to
        // short-circuit evaluation) and then 'm' is continuously incremented
        // until it goes out of bounds
        while (i == 0 || d != 0) {
        d = a1[i][m];    <------SEGFAULT per GDB
        ++m;
    }
    delta = (d - a1[i][j]) / m;
    n = j + 1;
    while (n < j + m) {
        a1[i][n] = a1[i][n - 1] + delta;
        ++n;
    }
}

【讨论】:

    【解决方案3】:

    问题出在以下几行:

    while (i == 0 || d != 0) {
            d = a1[i][m];    <------SEGFAULT per GDB
            ++m;
    }
    

    当 i 等于 0 时,您的 while 循环将继续进行。由于您从未在 while 循环中递增 i,因此 m 会一直递增直到超出范围,从而导致您遇到的段错误问题.

    确保检查i 和m 的值,确保它们在分配的内存范围内,并且您的代码可以正常工作。

    【讨论】:

      猜你喜欢
      • 2015-09-29
      • 2021-10-23
      • 1970-01-01
      • 1970-01-01
      • 2013-08-07
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      相关资源
      最近更新 更多