【问题标题】:Only able to print entry of an array at most twice [closed]最多只能打印两次数组的条目[关闭]
【发布时间】:2015-08-30 14:00:17
【问题描述】:

当我从命令行运行包含具有以下代码的函数的可执行文件时,result[1] 仅在程序崩溃之前打印两次(“*.exe 已停止工作”),即使块长度设置为 25。

当我双击运行完全相同的可执行文件时,程序崩溃而没有打印任何内容。 (但它会一直运行到 for 循环之前)

result 是一个 double 类型和长度 blocklength 的数组,它作为参数传递给函数。

for (int i = 0; i < blocklength; i++) {
    cout << result[1] << endl;
}

当我使用 GNU 项目调试器 (GDB) 逐步检查程序时,它打印出 result[1] 25 次并且没有崩溃。

显然,最初的 for 循环不仅仅是一遍又一遍地打印相同的值,但我将问题缩小到这个范围,现在完全陷入困境和困惑。

非常感谢任何帮助或意见。

这是完整的代码,result在主函数中定义为 double* result = new double[blocklength] 并立即传递给函数:

void entropy(char* input, int l_input, double* result, int blocklength, char order)
{
    int l_counter = pow(order, blocklength);
    int* counter = new int[l_counter];
    double prob = 0;
    int max_counter = 1;
    int* temp = new int[l_input];

    for (int i = 0; i < l_input; i++) {
        temp[i] = 0;
    }

    for (int s = 1; s <= blocklength; s++)
    {
        max_counter *= order;

        // reset counter
        for (int i = 0; i < max_counter; i++) {
            counter[i] = 0;
        }

        // init result
        result[s] = 0;


        for (int b = 0; b < l_input + 1 - s; b++) {
            temp[b] = order * temp[b] + input[b - 1 + s];
            counter[temp[b]]++;
        }

        for (int b = 0; b < max_counter; b++) {
            prob =  counter[b] / (double)(l_input - s + 1);
            if (prob != 0)
            {
                result[s - 1] = result[s - 1] + fabs(prob * log(prob));
            }
        }

        std::cout << "Block " << s << " okay" << std::endl;
    }

    cout << "sum done" << endl;

    for (int i = 0; i < blocklength; i++)
    {
        cout << result[1] << endl;
    }

    std::cout << "Entroyp done!" << std::endl;
}

【问题讨论】:

  • 你必须提供更多的代码,从这里的代码可能没有人能够推断出哪里出了问题。据我所见,您提供的 3 行没有任何问题,但我怀疑您在某处更改了数组的地址而不是更改其元素的值。
  • blocklength 是一个字符。对吗?
  • 是的,blocklength 是一个字符,这是个问题吗?
  • 您对blocklength 的使用是int,而不是char。你在整数计算中使用它,迭代一个数组。为什么它甚至是一个字符?除此之外,它是一个signed char,所以它的范围是 -128 到 127(如果你的数组长度超过 127,那就有问题了)。
  • result[s]cout &lt;&lt; result[1] &lt;&lt; endl; 是潜在的段错误。 s 是一个循环变量,从值 1 开始,而不是 0,因此会有一个无效访问。如果 blocklength == 1,则打印 result[1] 将导致另一个无效访问。

标签: c++ arrays crash cout


【解决方案1】:

您的代码有 2 个问题。 result[s] 在初始化后不会被读取/写入。

result[s] = 0; 

访问的是 result[s-1]。

result[s - 1] = result[s - 1] + fabs(prob * log(prob));

这意味着 result[0] 永远不会被设置为 0。这也意味着 result[blocklength] = 0 将被分配但永远不会被使用。

如果您的代码中有int* result = new int[blocklength]; 之类的行,那么您访问的值根本不在您的数组中。有效索引介于 0 和 arrayLenght-1 之间。

或更笼统地说: 如果您的输入错误,您的程序就会崩溃。您必须确保不会访问超出数组容量的值,这应该在访问它的行/循环中完成,而不是在其他地方。

在这种情况下,您必须确保结果容量至少为块长度+1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多