c++ - 分段故障。是因为坏指针吗?

标签 c++ pointers for-loop memory-leaks

为什么我会收到此段错误(核心转储)?我最初被告知这是因为我的指针 p_p_tictactoe = new char*[cols],但我被告知的是不对的。每组代码的用途在整个代码中都有注释。代码正在运行,但我得到了这个结果。我知道 for 循环必须是这个的主要问题。

Please enter a number of rows: 4
Please enter number of columns: 3
Enter a single character for position( << i << ): a  
Enter a single character for position( << j << ): b  
Segmentation fault (core dumped)



 #include <iostream>

        using namespace std;

        int main()
        {
           // TODO:  Below each Bp_tictactoe` of type pointer-to-a-pointer-to-a-char
       char **p_p_tictactoe;


       // 2. Prompt your user to enter a number of rows, then a number of columns.
       //    store their answers in the variables `rows` and `cols`.
       char rows;
       char cols;
       cout << "Please enter a number of rows: ";
       cin >> rows;
       cout << "Please enter number of columns: ";
       cin >> cols;
       // 3. Allocate a 1-dimensional array of pointers-to-chars (length == `rows`)
       //    and store its address in `p_p_tictactoe`
       p_p_tictactoe = new char*[rows];
       // 4. Use a for-loop to allocate a dynamic array of chars (length == `cols`)
       //    for i from 0 to rows - 1 and store its address in `p_p_tictactoe[i]`.
       for (int i = 0; i < rows - 1; i++)
       {
         p_p_tictactoe = new char*[cols];
       }
       // 5. Use a for-loop to prompt the user to enter a char for each position in
       //    (" << i << ", " << j << "): "
       //    As you read each char, store it in the array.
       // 6. Use a nested for-loop to print the array, one row per line.  The chars
       //    for each row should be space-separated.  For example, if the array is
       //    2 x 3 and stores the values A, B, C, X, !, &, the output should look
       //    like:
       //       A B C
       //       X ! &\


       char new_input1;
       char new_input2;
       for (int i = 0; i < rows; i++)
       {
          for (int j = 0; j < cols; j++)
          {
             cout << "Enter a single character for position( << i << ): ";
             cin >> new_input1;
             cout << "Enter a single character for position( << j << ): ";
             cin >> new_input2;
             *p_p_tictactoe[i] = new_input1;
             *p_p_tictactoe[j] = new_input2;
             cout << *p_p_tictactoe[i] <<endl;
          }  
       }
       // *** Prevent memory leaks by deallocating dynamic memory when you are done
       // using it. ***

       // 7. Use a for-loop to delete each row of the dynamic array.                


       // 8. Delete the pointer-to-a-pointer to release the array of row pointers,
       //    and set its value to NULL to avoid accessing invalid memory.
for (int i = 0; i < 3; i++)
{
delete[] p_p_tictactoe[i];
delete[] p_p_tictactoe;
}
cout << "Bye!" << endl;
return 0;
    }

最佳答案

除其他外,您对 p_p_tictactoe 的分配不正确。这是一个双指针,这仅仅意味着它是一个指向指针数组的指针。你的两步分配是正确的想法,但你在 for 循环中的内容是不正确的。在 p_p_tictactoe = new char*[rows] 行之后,您现在有一个指向 char* 类型数组的指针。因此,如果 rows 为 4,则内存中的内容现在如下所示:

 p_p_tictactoe[0] == char* --> junk
              [1] == char* --> junk
              [2] == char* --> junk
              [3] == char* --> junk

您现在必须遍历这 4 个 char* 中的每一个并为它们分配空间。每个 char* 必须指向一个 chars 数组。这是注释为您提供有关循环和使用 p_p_tictactoe[i] 索引的提示的地方:

 for (int i = 0; i < rows - 1; i++)
 {
   p_p_tictactoe[i] = new char[cols];
 }

现在,对于 cols == 3,在内存中你有:

 p_p_tictactoe[0] == char* --> 3 consecutive bytes
              [1] == char* --> 3 consecutive bytes
              [2] == char* --> 3 consecutive bytes
              [3] == char* --> 3 consecutive bytes

您发布的代码是内存泄漏。每次执行 p_p_tictactoe = new char*[#] 时,操作系统都会进入堆以获得足够的内存来分配。您没有跟踪先前的指针,也没有先释放它,因此分配的内存现在没有指向它的东西。

同样的理论也适用于释放内存。你最后得到的不太正确。解除分配始终是分配的镜像。这显然是一项家庭作业,所以我不会发布该代码,但它与分配相同,只是相反。

我强烈推荐使用 gdb,这是一个用于 linux 的文本调试器(或任何等效的调试器)。如果你希望在 C/C++ 中成功编码,你必须了解内存在堆栈和堆上的工作方式,你必须学习如何正确管理它,否则你将陷入痛苦的境地。 gdb 起初有点令人生畏,但它会让您打印出内存地址并检查内存,这对学习和强化您认为自己知道的内容非常有帮助。

关于c++ - 分段故障。是因为坏指针吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35423603/

相关文章:

batch-file - 在批处理文件的 for 循环中转义括号

c++ - 如何在 C++ 的 do while 循环中读取空格

c++ - 什么保证重载的非常量方法被调用?

c++ - 带有指针 vector 的 SWIG 和 C++ 内存泄漏

c - 将指针传递给函数异常

javascript - 用数字 5 从数组中过滤数字

c++ - 在基于C++范围的循环中使用&运算符..令人困惑

c++ - 根据 "auto(x)"论文(wg21.link/p0849),为什么 "return std::forward<T>"无法完美转发 "T&&"输入的参数?

c - C 中指向数组的指针

C++ 指针引用、类和指针列表、奇怪的返回