簡體   English   中英

Scanf 和動態內存分配

[英]Scanf and Dynamic memory allocation

int **elem;
elem = (int **)malloc(sizeof(int**) * numCol);

        for (i = 0; i < 2; i++)
        for (j = 0; j < numCol; j++)
        {
            scanf("%d", &elem[i][j]); //Shouldn't it give a value to the address pointed by 
                                     //a pointer to pointer to int?

        }

為什么此代碼會出現分段錯誤錯誤?(分段錯誤:11)此代碼有效:

int **elem;
elem = (int **)malloc(sizeof(int**) * numCol);

        for (i = 0; i < 2; i++)
        {
        elem[i] = (int *)malloc(numCol * sizeof(int));

        // Fill it with values

        for (j = 0; j < numCol; j++)
        {
            scanf("%d", &elem[i][j]);
        }

我糊塗了。 除了那個分割問題之外, int ** 的值不是 4 嗎? 為什么不直接使用 int。

第一個代碼片段出現段錯誤,因為您沒有為數組列分配任何內存 - 每個elem[i]都沒有指向任何有意義的內容。

像這樣分配“鋸齒狀”數組的一般模式如下:

/**
 * Allocate N "rows", which is actually an array of 
 * pointers to T
 */
T **arr = malloc( sizeof *arr * numRows ); // for any type T
if ( arr )
{
  /**
   * For each "row", allocate an array of T
   */
  for ( size_t i = 0; i < numRows; i++ )
  {
    arr[i] = malloc( sizeof *arr[i] * numCols );
    if ( arr[i] )
    {
      for ( size_t j = 0; j < numCols; j++ )
      {
        // initialize arr[i][j]
      }
    }
  }
}

圖片可能會有所幫助。

首先從arr指針開始:

     T **
     +–––+
arr: |   |
     +–––+

然后你分配一個指向T的指針數組作為你的“行”(為了使圖片保持合理的大小,我們假設兩行兩列):

     T **      T *
     +–––+     +–––+
arr: |   | ––> |   | arr[0]
     +–––+     +–––+
               |   | arr[1]
               +–––+

最后,您為每個“行”分配T數組:

     T **      T *               T
     +–––+     +–––+             +–––+
arr: |   | ––> |   | arr[0] –––> |   | arr[0][0]
     +–––+     +–––+             +–––+
               |   | arr[1] –+   |   | arr[0][1]
               +–––+         |   +–––+
                             |
                             |   +–––+
                             +-> |   | arr[1][0]
                                 +–––+
                                 |   | arr[1][1]
                                 +–––+

不能保證sizeof (int **)sizeof (int *)sizeof (int) (在 x86_64 上,指針大小通常為 8 字節)。

請注意,使用這種零碎分配,行在內存中不會連續 - arr[1][0]不會緊跟在arr[0][1]

我糊塗了。 除了那個分割問題, int ** 的值不是 4 嗎? 為什么不直接使用 int。

並非在所有機器中都是如此,因此在 sizeof 函數中使用正確的類型是正確的,以避免在程序運行時發現復雜的錯誤。

為什么這段代碼會出現分段錯誤?(Segmentation fault: 11)這段代碼有效嗎?

第一段代碼在為int** elem動態分配內存時出錯,實際上您只在矩陣中分配了一行。

在第二個代碼中,您對矩陣進行了正確的初始化。 在第二個代碼中注意你的周期是 i<2。 僅當numCol等於 2 時,此初始化才是正確的。

更好的代碼可以是這樣的:

int **elem;
elem = (int **)malloc(sizeof(int*) * numCol); //a correction in sizeof

        for (i = 0; i < numCol; i++) //cycle on numCol and not on 2
        {
            elem[i] = (int *)malloc(numCol * sizeof(int));

            // Fill it with values

            for (j = 0; j < numCol; j++)
            {
                scanf("%d", &elem[i][j]);
            }
 }

暫無
暫無

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

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