Почему free (arr) удаляет только первые два элемента массива? - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть простой код:

#include  <stdio.h>
#include  <stdlib.h>

int main(void)
{
    int elms = 5;
    int* a = (int*) calloc(elms, sizeof(int));

    *a = elms;
    for(int i = 1; i < elms; i++){
        *(a + i) = i;
    }

    for(int i = 0; i < elms; i++){
        printf("%d ", *(a + i));
    }

    printf("\n");

    free(a);
    // create new array with size increased by one
    int* arr = (int*) realloc(a, (elms + 1) * sizeof(int));
    *(arr + elms) = 10;

    for(int i = 0; i < elms + 1; i++){
        printf("%d ", *(arr + i));
    }

    printf("\n");    

    return 0;
}

запустить на rextester

Здесь я получаю вывод как:

5 1 2 3 4 
0 0 2 3 4 10 

Myвопрос в том, почему при вызове free() удаляются только первые два элемента массива?Либо он должен был удалить только первый элемент, либо все элементы, но почему два элемента?

Если я прокомментирую вызов free(), я получу ожидаемый результат:

5 1 2 3 4 
5 1 2 3 4 10 

Примечание: выход не изменится, если я переназначу значение realloc обратно на a, как и ожидалось.

Ответы [ 3 ]

0 голосов
/ 15 ноября 2018

Вы вызываете неопределенное поведение с помощью:

free(a);
// create new array with size increased by one
int* arr = (int*) realloc(a, (elms + 1) * sizeof(int));

За 7.22.3.5 Функция realloc , параграф 3 стандарта C (выделение жирным шрифтом):

, если ptr не совпадает с указателем, ранее возвращенным функцией управления памятью, или если пространство было освобождено путем вызова функции free или realloc,поведение не определено.

0 голосов
/ 15 ноября 2018

В дополнение к другим ответам:

Вы, вероятно, хотите это:

#include  <stdio.h>
#include  <stdlib.h>

int main(void)
{
  int elms = 5;
  int* a = (int*)calloc(elms, sizeof(int));

  *a = elms;
  for (int i = 1; i < elms; i++) {
    *(a + i) = i;
  }

  for (int i = 0; i < elms; i++) {
    printf("%d ", *(a + i));
  }

  printf("\n");

  // << don't call free(a) here, once you've done that
  //    a is "gone" forever.

  // create new array with size increased by one
  // << we use the same variable a as before, using another
  //    variable arr as you did is useless and confusing
  a = (int*)realloc(a, (elms + 1) * sizeof(int));
  *(a + elms) = 10;

  for (int i = 0; i < elms + 1; i++) {
    printf("%d ", *(a + i));
  }

  free(a);  // << call free(a) here once you're done with a

  printf("\n");    
  return 0;
}

Посмотрите комментарии, начинающиеся с <<

Выход:

5 1 2 3 4
5 1 2 3 4 10
0 голосов
/ 15 ноября 2018

Ваш код имеет неопределенное поведение. В частности:

free(a);
... realloc(a, ...);

После free(a) значение a является неопределенным. Попытка что-либо с ним сделать (например, передать его функции) имеет неопределенное поведение.

Разрешен любой результат.

...