【问题标题】:Segmentation Fault (Cored Dumped) When Creating 3D Array w/ Pointers使用/指针创建 3D 数组时出现分段错误(核心转储)
【发布时间】:2014-01-25 02:44:29
【问题描述】:

提前感谢您的帮助!

我目前正在阅读 Alex Alllain 的“Jumping into C++”,到目前为止,它是一本很棒的书,就 C++ 速成课程而言。至少对我来说是。我在第 14 章讨论使用 2D 数组的指针和其中一个练习问题的任何人都要求读者创建一个 3D 乘法表数组,该数组具有用户在运行时选择的任意长度、宽度和高度。我想我的代码已经准备好并且可以工作了,感谢这里的某个人,我能够摆脱与使用指针创建 3D 数组相关的所有编译错误。

我会发布我的问题的图片,但我的声誉当然不够高。基本上,在我编译并运行程序之后,我输入了 3D 数组的高度、宽度和深度的 3 个单独维度,然后我得到了令人兴奋的消息“分段错误(核心转储)。我的代码中有一些调试 cout 消息,但是它们都没有出现,这让我感到困惑。我不明白为什么我的代码最早会在第一条调试消息之前崩溃。唯一一次它在任何地方都是如果我为所有三个值输入 1。但是只有调试消息显示出来,但实际上并没有像我认为的那样打印。

这是我的代码:

#include <iostream>

using namespace std;

void printMultTable(int*** p_cube, int height, int width, int depth);

int main() {
    int height = 0;
    int width = 0;
    int depth = 0;

    // Get user input for height, witdth, and depth of multiplication cube
    cout << "Enter height:  ";
    cin >> height;

    cout << "Enter width:  ";
    cin >> width;

    cout << "Enter depth:  ";
    cin >> depth;

    cout << "Made it to point A";

    // Create pointer to pointer for multiplication tables
    int ***p_cube = new int**[depth]; // Creates pointer to 2D pointer array (Layers of Cube)

    cout << "Made it to point B";

    for (int i = 0; i < height; i ++) {
        p_cube[i] = new int*[height]; // Creates pointer to 1D array (Columns of Cube)
        for (int j = 0; i < width; i++) {
            p_cube[i][j] = new int[width]; // Creats pointers that are arrays (Rows of Cube)
        }
    }

    cout << "Made it to point C";


    // Create multiplication table
    for (int i = 0; i < depth; i++) {
        for (int j = 0; j < height; j++) {
            for (int k = 0; k < width; k++) {
                p_cube[i][j][k] = (j+1) * (k+1);
            }
        }
    }

    cout << "Made it to point D";

    // Use printMultTable to print out multiplication table
    printMultTable(p_cube, height, width, depth);

    // Deallocate memory taken by pointers
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++){
            delete[] p_cube[i][j];
        }
        delete p_cube[i];
    }
    delete[] p_cube;
}

void printMultTable(int*** p_cube, int height,int width,int depth) {
    for (int i = 0; i < depth; i++) {
        for (int j = 0; j < height; j++) {
            for (int k = 0; k < width; k++) {
                cout << p_cube[i][j][k] << "\t";
            }
            cout << "\n";
        }
        cout << "\n\n\n";
    }
}

您可能会注意到,我有 4 个单独的调试检查点,上面写着“到达 __ 点”。问题是它甚至不能指向“A”。我不确定这是否是编译器跳过的错误,因为它认为代码是洁净的,或者它是否与我的计算机有关或其他我想不到的东西。指针必须是我所学过的最令人困惑的东西哈哈。

我们将不胜感激任何和所有的帮助或想法!

谢谢! 扎克

【问题讨论】:

  • 从硬编码 3 个值开始,去掉 >> 看看你的代码是否有效。然后回来,我个人猜测你正在点击返回而不是值,或者它看到了额外的返回并且 int 无效。您可以将 int 值从 cin 转换为字符串,然后在将其转换为 int 之前检查它是否为有效值,这样您就可以更优雅地失败。

标签: c++ arrays pointers multidimensional-array


【解决方案1】:

这段代码:

for (int i = 0; i < height; i ++) {
    p_cube[i] = new int*[height]; // Creates pointer to 1D array (Columns of Cube)
    for (int j = 0; i < width; i++) {
        p_cube[i][j] = new int[width]; // Creats pointers that are arrays (Rows of Cube)
    }
}

应该是:

for (int i = 0; i < depth; i ++) {
    p_cube[i] = new int*[height]; // Creates pointer to 1D array (Columns of Cube)
    for (int j = 0; j < height; j++) {
        p_cube[i][j] = new int[width]; // Creats pointers that are arrays (Rows of Cube)
    }
}
  • 第一个for循环必须从0到depth
  • 第二个for循环必须从0到height
  • 您在第二个 for 循环中比较和增加 i 而不是 j

【讨论】:

  • 这成功了!你是一个圣人ichramm!感谢大家这么快的帮助!这种解释对我来说最有意义,并有助于阐明如何构造创建指向指针数组结构的指针的循环。此外,Dietmar,我将不得不开始仔细检查以确保我开始对我的代码进行检查,从而为我的代码提供更高的稳定性和安全性。再次感谢大家的帮助!
【解决方案2】:

最明显的问题是您使用height 作为第一个循环的范围,而有depth 对象。

int ***p_cube = new int**[depth];
// ...
for (int i = 0; i < height; i ++) {
    p_cube[i] = new int*[height];
    // ...
}

如果depth != height,您将有超出范围的访问,或者您将访问未初始化的内存。

另一个问题是你不检查你的分数,这是一个非常坏主意!如果输入失败,您将获得一个随机值。阅读后总是检查它是否成功:

if (std::cin >> depth) { ... }

如果这本书的作者提倡赤裸裸的分配和未经检查的阅读,他会对你造成极大的伤害!

【讨论】:

    【解决方案3】:

    祝你学习顺利!

    首先,我认为像这样学习 int*** 并不是一个好的开始方式,因为它非常混乱且效率低下。我建议简单地分配一块具有宽度*高度*深度元素的内存。要遍历元素,您可以简单地从 [0 .. width*height*depth] 迭代索引。要访问特定元素,您可以这样计算:index = i*(width*height) + j*(width) + k。

    但是为了回答你的问题,我注意到你在这里犯了一个错误:

    int ***p_cube = new int**[depth];
    for (int i = 0; i < height; i ++) {
        p_cube[i] = new int*[height];
        ...
    

    您已经创建了一个新的 int** 数组,其大小为“深度”,但随后您对其进行迭代,就好像其中包含“高度”元素一样。正确的做法是遍历“深度”元素,并分配一个 int* 数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-04
      • 2015-05-12
      • 2016-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多