簡體   English   中英

分段故障。 是因為指針錯誤?

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

為什么會出現此細分錯誤(核心轉儲)? 最初告訴我這是因為我的指針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]索引的提示的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起初有點令人生畏,但是它可以讓您打印出內存地址並檢查內存,這對於學習和重新執行您認為的內容非常有幫助。

我認為這里的問題是,您應該為雙指針變量采用一個雙精度數組..您將兩個不同的東西重新分配給一個變量..

代碼的一個問題是您的寬度和高度沒有按照您認為的方式被解釋。 當您編寫此代碼時:

char width;
cin >> width;

...結果程序讀取一個字符,並將其ASCII值分配給width 因此,如果輸入“ 4”,則width == 52值為true ,而width == 4 false (但是width == '4'true因為'4' == 52 )。

這個問題很容易解決:只需使用int代替char 無論如何,您不會節省任何內存,因為new可能正在創建字對齊的指針。

這是Tarang Gupta指出的問題的補充。

這是因為行:

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

您將其視為2維數組。

以下內容寫錯了:

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

首先,您為p_p_tictactoe分配了一個大小為sizeof (char*[rows])並將其內容替換p_p_tictactoe = new char*[cols]; (int)row時間。 您的代碼中有很多未使用和未引用的內存。

即使在更改代碼以防止此錯誤之后,以下操作仍會引起問題:

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

您將p_p_tictactoe 3次刪除p_p_tictactoe分配和引用的空間。 它應該已經超出循環范圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM