简体   繁体   English

分段故障。 是因为指针错误?

[英]Segmentation Fault. Is it because of bad pointer?

Why am I getting this Segmentation Fault(core dump)? 为什么会出现此细分错误(核心转储)? I was originally told it is because of my pointer p_p_tictactoe = new char*[cols], but what I was told was not right.The purpose of each set of code is commented throughout the code. 最初告诉我这是因为我的指针p_p_tictactoe = new char * [cols],但是告诉我的是不对的。每组代码的目的在整个代码中都有注释。 The code is running, but I am getting this result. 代码正在运行,但是我得到了这个结果。 I know the for-loop has to be the main problem for this. 我知道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;
    }

among other things, your allocation of p_p_tictactoe is incorrect. 除其他外,您对p_p_tictactoe的分配不正确。 This is a double pointer, which simply means it's a pointer to an array of pointers. 这是一个双指针,仅表示它是指向指针数组的指针。 Your two-step allocation is the correct thought, but what you have in the for loop is incorrect. 您的两步分配是正确的想法,但是您在for循环中所拥有的是不正确的。 After the line p_p_tictactoe = new char*[rows] , you now have a pointer to an array of char* types. p_p_tictactoe = new char*[rows] ,您现在有了一个指向char*类型数组的指针。 So if rows is 4, what you have in memory now looks like: 因此,如果rows为4,则您现在的内存如下所示:

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

You now have to loop through each of these 4 char* and allocate space for them. 您现在必须遍历这4个char*每一个并为其分配空间。 Each char* must point to an array of chars . 每个char*必须指向chars数组。 This is where the comment gives you the hint about looping through and using the p_p_tictactoe[i] indexing: 这是注释为您提供有关遍历和使用p_p_tictactoe[i]索引的提示的p_p_tictactoe[i]

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

Now, for cols == 3 , in memory you have: 现在,对于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

The code you posted is a memory leak. 您发布的代码是内存泄漏。 Every time you do p_p_tictactoe = new char*[#] , the OS goes to the heap to get enough memory for the assignment. 每次执行p_p_tictactoe = new char*[#] ,操作系统都会进入堆以获取足够的内存用于分配。 You are not keeping track of the previous pointer nor freeing it first, so that's allocated memory that now has nothing pointing to it. 您不必跟踪先前的指针,也不先释放它,因此分配的内存现在没有指向它的指针。

And the same theory applies to freeing memory. 同样的理论也适用于释放内存。 What you have at the end is not quite right. 最后您拥有的不是很正确。 Deallocation is always a mirror image of the allocation. 解除分配始终是分配的镜像。 This is clearly a homework assignment, so I won't post that code, but it's the same as the allocation except in reverse. 显然,这是一项家庭作业,因此我不会发布该代码,但是除了反向之外,它与分配相同。

I'd highly recommend using gdb , which is a text debugger for linux (or any equivalent debugger). 我强烈建议使用gdb ,它是linux的文本调试器(或任何等效的调试器)。 If you want any hope of successfully coding in C/C++, you have to learn how memory works on both the stack and heap, and you have to learn how to correctly manage it, or you will be in for a world of hurt. 如果您希望成功使用C / C ++进行编码,则必须学习内存在堆栈和堆上的工作方式,并且必须学习如何正确地对其进行管理,否则您将遭受重创。 gdb is a little daunting at first, but it will let you print out memory addresses and examine memory which is very helpful for learning and re-enforcing what you think you know. gdb起初有点令人生畏,但是它可以让您打印出内存地址并检查内存,这对于学习和重新执行您认为的内容非常有帮助。

我认为这里的问题是,您应该为双指针变量采用一个双精度数组..您将两个不同的东西重新分配给一个变量..

One problem with your code is that your width and height aren't getting interpreted the way you think they are. 代码的一个问题是您的宽度和高度没有按照您认为的方式被解释。 When you write this: 当您编写此代码时:

char width;
cin >> width;

...the resulting program reads one character and assigns its ASCII value to width . ...结果程序读取一个字符,并将其ASCII值分配给width So if you entered '4', then width == 52 would evaluate to true , and width == 4 would be false . 因此,如果输入“ 4”,则width == 52值为true ,而width == 4 false (But width == '4' would be true because '4' == 52 ). (但是width == '4'true因为'4' == 52 )。

This problem is easy to fix: Just use int instead of char . 这个问题很容易解决:只需使用int代替char You're not saving any memory anyway, because new is probably creating word-aligned pointers. 无论如何,您不会节省任何内存,因为new可能正在创建字对齐的指针。

That's in addition to the problem pointed out by Tarang Gupta. 这是Tarang Gupta指出的问题的补充。

It is because of the lines: 这是因为行:

*p_p_tictactoe[i] = new_input1;
*p_p_tictactoe[j] = new_input2;

You are treating it as an array with 2 dimensions. 您将其视为2维数组。

the following is written wrongly: 以下内容写错了:

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

You first allocated a space to p_p_tictactoe of size sizeof (char*[rows]) and replacing its contents with p_p_tictactoe = new char*[cols]; 首先,您为p_p_tictactoe分配了一个大小为sizeof (char*[rows])并将其内容替换p_p_tictactoe = new char*[cols]; for (int)row times. (int)row时间。 There is a lot of unused and unreferenced memory in your code. 您的代码中有很多未使用和未引用的内存。

Even after you change your code to prevent this error, the following will cause problems yet again: 即使在更改代码以防止此错误之后,以下操作仍会引起问题:

for (int i = 0; i < 3; i++)
{
    delete[] p_p_tictactoe[i];
    delete[] p_p_tictactoe;
}

You are deleting the space allocated and referenced by p_p_tictactoe 3 times in a row. 您将p_p_tictactoe 3次删除p_p_tictactoe分配和引用的空间。 It should have been outside the loop. 它应该已经超出循环范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM