【问题标题】:Different outputs after debugging and compiling C++ programs调试和编译 C++ 程序后的不同输出
【发布时间】:2010-01-01 22:07:41
【问题描述】:

我在 XP 虚拟机中的 MingW 编译器上运行 CodeBlocks。我写了一些简单的代码,可在cl1p 访问,它回答了CodeChef 的算法问题(好吧,它只回答了部分问题,因为我还没有包含多个测试用例的循环。

但是,我的问题是,在调试模式下运行它时,它会为输入提供正确的输出 5:

3
1
2 1
1 2 3

但是,当我构建并运行它时,它给出了荒谬的巨大输出 131078,这对我来说似乎是垃圾。我不明白这是怎么回事,但我猜这与动态内存分配有关。这里有什么问题,我该如何解决?我什至通过BotSkool 的在线编译器运行它,它运行良好。为测试用例添加循环后,代码甚至在 CodeChef 上都能正常运行!

#include <iostream>

using namespace std;

int main()
{
    // Take In number of rows
    int numofrows;
    cin >> numofrows;

    // Input Only item in first row
    int * prevrow;
    prevrow = new int[1];
    cin >> prevrow[0];

    // For every other row
    for (int currownum = 1; currownum < numofrows; currownum++)
    {
        // Declare an array for that row's max values
        int * currow;
        currow = new int[currownum+1];

        int curnum;
        cin >> curnum;

        // If its the first element, max is prevmax + current input
        currow[0] = prevrow[0] + curnum;

        // for every element
        int i = 1;
        for (; i <= currownum; i++)
        {
            cin >> curnum;

            // if its not the first element, check whether prevmax or prev-1max is greater. Add to current input
            int max = (prevrow[i] > prevrow[i-1]) ? prevrow[i] : prevrow[i-1];

            // save as currmax.
            currow[i] = max + curnum;
        }

        // save entire array in prev
        prevrow = new int[i+1];
        prevrow = currow;
    }

    // get highest element of array
    int ans = 0;
    for (int j=0; j<numofrows; j++)
    {
        if (prevrow[j] > ans)
        {
            ans = prevrow[j];
        }
    }

    cout << ans;
}

【问题讨论】:

  • 你应该发布实际代码,而不是链接。

标签: c++ debugging compilation garbage


【解决方案1】:

在 Linux 机器上通过 Valgrind 运行代码,您会惊讶于您的代码泄漏内存的地方有多少。 如果您正在走管理内存的艰难道路,请做好并在分配更多内存之前“删除”所有新分配的内存。 另一方面,如果您更喜欢简单的道路,请使用 std::vector 并忘记内存管理。

【讨论】:

  • 哇。我完全不知道向量,并且觉得很愚蠢,因为它确实出现在搜索与 Java 中的 ArrayList 等效的 C++ 时。无论如何,谢谢,这些知识将对我有很大帮助。您推荐任何网站来学习 C++ 中的所有其他数据结构?此外,Valgrind 站点不提供二进制文件。你知道我可以在哪里获得 Mac OS X 的二进制文件吗?我现在在我的 Mac 上安装了不兼容的旧版本 XCode,并且不想现在尝试构建应用程序(对于 Unix 命令行不太好)
  • 在您的书签中包含cplusplus.com/referencecppreference.com/wiki/start 以作为初学者:) 在那里您可以找到C++ 标准库中提供的数据结构和算法。关于它们的教程比比皆是。谷歌!
  • Valgrind 尚未以二进制形式提供给 Mac OS X,但您在 Mac OS X 中有替代品。XCode 提供了多种免费工具,例如 Instruments 和 MallocDebug。
【解决方案2】:

一方面,这是:

    //save entire array in prev
    prevrow = new int [i+1];
    prevrow = currow;

复制指针,而不是整个数组。

【讨论】:

  • 你确定吗?我想要一种将 currow 的所有值复制到 prevrow 的方法。我该怎么做?
  • 一种方法是 memcpy:memcpy(prevrow, currow, sizeof(int) * i);
【解决方案3】:

在你的循环中,你有这一行

int max = (prevrow[i]>prevrow[i-1])?prevrow[i]:prevrow[i-1];

在主循环的第一次迭代中,当currownum == 1 时,将进入包含该行的循环,因为i 被初始化为1。但是在第一次迭代中,prevrow 只有一个元素,并且这一行尝试访问prevrow[1]。在调试构建中,内存只是简单地初始化为零,但在正常构建中,您会得到一些恰好在内存中的垃圾值,从而导致您看到的结果。

几乎总是,当您在正常构建中获得垃圾值,但在调试构建中一切正常时,您正在访问一些未初始化的内存。

此外,您的程序正在疯狂地泄漏内存。例如,您不需要将循环内new 的任何结果分配给prevrow,因为在此之后您更改prevrow 以指向另一个分配的内存块。此外,您应该致电delete 获取您不再使用的任何内存。

【讨论】:

    猜你喜欢
    • 2011-07-31
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    相关资源
    最近更新 更多