Объяснение о типах и переменных, используемых в коде malloc - PullRequest
0 голосов
/ 31 октября 2019

Мне нужны некоторые пояснения для некоторых команд в этом конкретном фрагменте кода:

#inlcude <stdlib.h>
#define PTRS 5

char *p[PTRS];

size_t nbytes = 10;
int i;
/* Allocating memory */
for (i=0; i<PTRS; i++){
    printf("malloc of %10lu bytes ", nbytes);

    if ((p[i] = (char *)malloc(nbytes)) == NULL){
        printf("failed\n");
    } else {
        printf("succeeded\n");
    nbytes *= 100;
}
/* Free the memory allocated */
for (i=0; i<PTRS; i++){
    if(p[i]){
        free(p[i]);
        p[i] = NULL;
    }
}

Первый -
char *p[PTRS];
Объявляет ли эта строка указатель на массив или он объявляет массив указателей на символ?
p[i] = (char *)malloc(nbytes) Я понимаю, что при увеличении i, p[i]будет содержать указатель на выделенную память, вызываемую malloc, если она успешно обработана, и p[i] will be NULL`, если такая память не может быть подготовлена.
Второй -

if (p[i]){
    free(p[i]);
    p[i] = NULL;
}

Это освобождает память, только если p[i] имеет какое-либо значение (в данном случае указатель на память). Что произойдет, если мы удалим if(p[i]) и используем только free(p[i] и p[i] = NULL? Можем ли мы освободить указатель NULL?

Ответы [ 2 ]

2 голосов
/ 31 октября 2019
char *p[PTRS];

эквивалентно

char *(p[PTRS]);

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

char (*p)[PTRS];

Правило по часовой стрелке / спираль может быть полезно при расшифровке объявлений. Как и при использовании ресурса, такого как https://cdecl.org.


И вы можете передать указатель NULL на free (это не работает), поэтому проверка недействительно необходимо.

В зависимости от дальнейшего использования p, назначение p[i] = NULL может и не понадобиться.

1 голос
/ 31 октября 2019

Я понимаю, что при увеличении i p [i] будет содержать указатель на выделенную память, называемую malloc

Так что, если вы понимаете это, когда это означает, что p[i] существоэлемент массива имеет тип char *, потому что, по крайней мере, в программе есть явное приведение к этому типу вызова malloc в операторе if

 if ((p[i] = (char *)malloc(nbytes)) == NULL){

Так что это объявление

char *p[PTRS];

объявляет массив PTRS элементов с tyoe char *. Я советую написать такие объявления, как

char * p[PTRS];

, вставляя пробел после символа '*'.

Вы можете переписать объявление также следующим образом

char * ( p[PTRS] );

Указатель на массив PTRS элементов типа char объявляется следующим образом.

char ( *p )[PTRS];

Можем ли мы освободить указатель NULL?

Точнее было бы сказано, можем ли мы использовать функцию free с нулевым указателем, потому что мы не освобождаем сам нулевой указатель, который в контексте вашего примера имеет автоматическую продолжительность хранения.

Ответда, мы можем. Вызов функции с нулевым указателем не окажет никакого влияния и безопасен.

Таким образом, этот цикл

for (i=0; i<PTRS; i++){
    if(p[i]){
        free(p[i]);
        p[i] = NULL;
    }
}

может быть переписан как

for (i=0; i<PTRS; i++){
    free(p[i]);
    p[i] = NULL;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...