вопросы о malloc и указателях - PullRequest
0 голосов
/ 18 ноября 2018

Вчера нам показали эту программу в классе, и у меня есть вопрос относительно ее вывода.

malloc.c:

#include <stdlib.h>

int *create_array(int);

int *create_array(int elements) {
    int i,*x = (int *) malloc(elements*sizeof(int));

    for(i=0;i < elements;i++) {
        x[i] = i;
    }
    free(x);
    return x;
} 

int main(void) {
    int j, *arr;
    arr = create_array(5);
    for(j=0;j<5;j++) {
        printf("%d\n",arr[j]);
    }
    return 0;
}

Вопрос (ы):

Когда я запускаю программу, я получаю это как вывод:

1627793032
1627793104
2
3
4

Однако, не должны ли первые 2 элемента быть 0 и 1 соответственно?Значения, напечатанные здесь, кажутся мне адресами памяти, я прав?Кроме того, это из-за какой-то ошибки, вызывающей undefined behavior?

Ответы [ 2 ]

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

Реальный вопрос в том, почему вы вообще ожидаете, что это сработает? Вы освобождаете x, а затем возвращаете освобожденный указатель, который является бессмысленным.

Происходит следующее:

  • Внутри функции вы выделяете 5 пробелов, x указывает на первый свой адрес.

  • Вы пишете 0, 1, 2, 3, 4 в этих местах.

  • Вы освобождаете x, поэтому все 5 пробелов больше не зарезервированы.

  • Вы выходите из функции, делая так, чтобы 2 следующие свободные области памяти были используется, которые, как оказалось, те, где вы написали 0 и 1.

  • Вы печатаете значения, содержащиеся в 5 областях памяти, которые вы уже освобожден, где те, в которых вы написали 0 и 1, оказались повторно используется для чего-то другого; отсюда и странные цифры.

Как правило, не пытайтесь читать области памяти, которые я освободил; еще хуже, не пытайтесь писать там.

Доступ к нераспределенной памяти ведет к неопределенному поведению.

Кроме того, вам не нужно объявлять функцию в отдельной строке, если между ними ничего не будет; плюс вам не нужно приводить то, что возвращает malloc, к типу; это пустота *, которая по умолчанию может содержать все, что вы в нее бросаете. Важен ваш базовый тип переменной. Смотрите здесь

Исправленный код:

#include <stdlib.h>

int *create_array(int elements) {
    int i,*x = malloc(elements*sizeof(int));

    for(i=0;i < elements;i++) {
        x[i] = i;
    }
    return x;
} 

int main(void) {
    int j, *arr;
    arr = create_array(5);
    for(j=0;j<5;j++) {
        printf("%d\n",arr[j]);
    }
    free(arr);
    return 0;
}
0 голосов
/ 18 ноября 2018

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

Итак, да, это ошибка, приводящая к неопределенному поведению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...