2013-12-17 2 views
1

В принципе, я пытаюсь преобразовать кучу входов char в int и назначить их динамическому массиву int. Строковый ввод и токенизация работают нормально. Проблема (из того, что я могу сказать), по-видимому, связана с перераспределением массива int; после того, как массив перераспределяется дважды, указатель на массив int возвращает NULL.Проблемы с перераспределением при назначении строки динамическому массиву int

Что я пытался сделать, это удвоить размер массива int каждый раз, когда количество токенов соответствует или превосходит (размер делится на sizeof (int)). Оператор realloc работает каждый раз, когда это условие выполняется.

Я думал, что использование указателя на указатель было окончательным решением. Бьюсь об заклад, это какая-то действительно очевидная проблема, но я здесь нахожусь здесь. Если вы запросите дальнейшую разработку, я постараюсь изо всех сил. Поймите, что я только взял C в течение семестра и большую часть своей работы боролся.

Также, как было сказано, это было частью присвоения класса, которое с тех пор прошло. Я бы предпочел объяснить, что не так больше, чем полный код, если все в порядке.

У меня много заявлений printf, поэтому извиняйтесь за любой беспорядок.

EDIT: Заменены все экземпляры 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++; 
} 

Исходный код обновлен, чтобы отразить это. Для того, чтобы сделать это до смешного длинный пост чуть более подавленным, давайте состояние, что я сделал это в основной():

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

Функция ввода принимает как resize и arr. main отправляет тот же указатель на оба. Это ошибка.

При изменении размера resize, arr остается в силе и может указывать на недопустимый адрес (если realloc возвращает другой адрес).

Как исправить: Удалить аргумент функции arr и использовать только resize.

+0

Так что я должен был бы присвоить значения atoi как * resize [i] = atoi (results [j])? Когда я это сделал, первое значение нового массива int появилось просто отлично, но последовательные записи сбрасываются после того, как задание выполняется по последовательному индексу. Я скоро отредактирую сообщение. – user3109954

+0

Использование (* изменение размера) [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, вы получите переполнение буфера.

Смежные вопросы