简体   繁体   中英

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. The code is running, but I am getting this result. I know the for-loop has to be the main problem for this.

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. 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. After the line p_p_tictactoe = new char*[rows] , you now have a pointer to an array of char* types. So if rows is 4, what you have in memory now looks like:

 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. Each char* must point to an array of chars . This is where the comment gives you the hint about looping through and using the p_p_tictactoe[i] indexing:

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

Now, for cols == 3 , in memory you have:

 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. 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). 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. 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.

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

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 . So if you entered '4', then width == 52 would evaluate to true , and width == 4 would be false . (But width == '4' would be true because '4' == 52 ).

This problem is easy to fix: Just use int instead of char . You're not saving any memory anyway, because new is probably creating word-aligned pointers.

That's in addition to the problem pointed out by 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.

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]; for (int)row times. 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. It should have been outside the loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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