2013-12-17 95 views
1

基本上,我試圖將一堆char輸入轉換爲int,並將它們分配給一個動態int數組。字符串輸入和標記化似乎工作正常。這個問題(從我可以告訴的)似乎是重新分配int數組; 數組重新分配兩次後,指向int數組的指針返回NULL將字符串分配給動態int數組時重新分配問題

我試圖做的是每當令牌的數量達到或超過(大小除以sizeof(int))時,int數組的大小加倍。每當滿足這個條件時,realloc語句就起作用。

我認爲使用指針指針是最終的解決方案。我敢打賭這是一個非常明顯的問題,但我在我的智慧結束。如果您要求進一步闡述,我會盡我所能。明白我只拿了C一個學期,並且大部分時間都在掙扎。

另外,事實告訴,這是從那以後通過的類作業的一部分。如果沒有問題,我更願意解釋有關錯誤的內容,而不是完整的代碼。

我有很多的printf語句,所以任何混亂的道歉。

編輯:用* resize替換input()函數內的newArray的所有實例。然而,我從來沒有嘗試通過指針指向值,所以如果你知道我是如何搞砸的話,請隨時糾正我的句法示例。分段故障發生在這裏:

for (k = (numElem - count); k < numElem; k++) 
{ 
    printf("\nk = %i\n", k); 
    printf("j = %i\n", j); 
    printf("numElem = %i\n", numElem); 
    printf("results[j]: %s\n\n\n", results[j]); 

    /* Segmentation fault regardless of what is assigned 
    to *resize[k]. */ 
    *resize[k] = atoi(results[j]); // PROBLEM HERE 
    j++; 
} 

源代碼已更新,以反映此。爲了讓這個可笑的長帖子更加柔和一點,讓我們說我在main()中做了這個:

int *newArray = malloc(MAXTOKEN * sizeof(int)); 

    input(&newArray); 

    free(newArray); 

繼續前進。

/* String input takes in char values, 
tokenizes them, converts the results 
to int, assigns them to newresizeay. */ 
int input(int **resize) 
{ 
    int i, j, k, count; 

    int numElem = 0; 
    int currentSize = MAXTOKEN; 

    char str[MAXSTRING]; 
    char *results[MAXTOKEN]; 

    /* This entire loop takes place at least once, 
    provided the first input isn't NULL. */ 
    do 
    {  
     i = 0, j = 0, k = 0; 

     /* Char input process. Takes place until the user 
     presses ENTER. */ 
     printf("Input integer values separated by spaces, or " 
      "press ENTER to exit.\n"); 
     while (((str[i] = getchar()) != '\n') && (i < MAXSTRING)) 
      i++; 
     printf("\n\n"); 

     str[i] = '\0'; 


     /* Tokenization of the chars that were input */ 
     count = 0; 

     if (results[0] = strtok(str, " \t")) 
      count++; 

     while (results[count] = strtok(NULL, " \t")) 
      count++; 


     /* numElem = 1 if the first input prompt established 
     str[0] as NULL */ 
     if ((count < 1) && (numElem < 1))  
      count = 1; 

     numElem += count; 

     printf("numElem: %i\ncurrentSize: %i\n", numElem, currentSize); 

     /* If the number of elements to assign meet or surpass 
     the amount of [memory/sizeof(int)], exponentially 
     increase the size of the int resizeay. */ 
     if (numElem >= currentSize) 
     { 
      *resize = realloc(*resize, (currentSize) * sizeof(int)); 
      if (*resize == NULL) 
       printf("\n\nYep, it threw up.\n\n"); 
      currentSize *= 2; 
     } 


     printf("\nSize should be: %i\n", currentSize * 4); 
     printf("Actual size: %d\n", _msize(*resize)); 


     /* The tokenized chars are converted to integers and 
     assigned to the int resizeay. */ 
     for (k = (numElem - count); k < numElem; k++) 
     { 
      printf("\nk = %i\n", k); 
      printf("j = %i\n", j); 
      printf("numElem = %i\n", numElem); 
      printf("results[j]: %s\n\n\n", results[j]); 

      *resize[k] = atoi(results[j]); // PROBLEM HERE 
      j++; 
     } 

     for (i = 0; i < numElem; i++) 
      printf("resize[%i]: %i\n", i, *resize[i]);    

     printf("\n\n\n");  

    } while (str[0] != NULL); 

} 
+0

我還沒有深入瞭解這一點,但它看起來像一些堆腐敗問題。 –

回答

0

輸入功能同時接收resizearrmain向兩者發送相同的指針。這是一個錯誤。

當調整resize的大小時,arr保持不變,並可能指向無效地址(當realloc返回不同的地址時)。

如何修復: 刪除arr函數參數並僅使用resize

+0

因此,我必須將atoi值分配爲* resize [i] = atoi(results [j])?當我這樣做時,新的int數組的第一個值顯示得很好,但連續的條目在連續索引嘗試賦值時會崩潰。我會盡快編輯我的帖子。 – user3109954

+0

使用(* resize)[i]。 – egur

+0

你也可以聲明'int * arr = * resize;'並使用它。只有在返回之前更新調整大小。 'realloc'將在'arr'上運行。 – egur

0

當你調用realloc函數時,如果新的內存塊比前一個小,它將保持指向先前使用的內存塊的原始狀態。如果新的內存塊大於前一個,則系統將重新在堆上分配內存並釋放先前的內存。

0

在其他問題:

char *results[MAXTOKEN]; 

應該

char *results[MAXTOKEN + 1]; 

因爲這裏計數的最大值將在這個循環中MAXTOKEN:

while (results[count] = strtok(NULL, " \t")) 
    count++; 

char str[MAXSTRING]; 

是非常可怕的,因爲只要用戶輸入超過MAXSTRIN(= 11)個字符而沒有按下Enter鍵,就會發生緩衝區溢出。