Проверьте после malloc и прежде чем звонить бесплатно () - PullRequest
0 голосов
/ 30 сентября 2019

Я прочитал этот пост о проверке, прежде чем звонить бесплатно (). Я хочу подтвердить это с помощью кейса.

Следующие коды скопированы из моего проекта C ++ (проверено, ошибок нет / предупреждения). Я просто хочу подтвердить правильный способ проверки выделения памяти и free () in C ++ .

// part 1: declare 
typedef struct cipher_params_t {
    unsigned char * p1;     
    int p2;                 
}cipher_params_t;

// part 2: allocate memory
cipher_params_t *params = (cipher_params_t*)malloc(sizeof(cipher_params_t));

// part 3: check allocate memory
if (!params) {
    /* Unable to allocate memory on heap*/
    fprintf(stderr, "ERROR: malloc error: %s\n", strerror(errno));
    return errno;
}

// part 4: assign values
unsigned char key[16] = {0x01, 0x02, ..., 0x0f};
params -> p1 = key;
params -> p2 = 1;

// part 5: use params for some function
some_func(params);

// part 6: free params lastly
cleanup1(params);
// cleanup2(params); //another option

void cleanup1 (cipher_params_t *params){
    if(params) free(params)
}

void cleanup2 (cipher_params_t *params){
    if(params!=NULL) free(params)
}

Вопросы:

  1. В части 3, это правильный способ проверить, если (! Params). Любая ошибка здесь не рассматривается?

  2. В части 6 я даю 2 варианта - if (params) и if (params! = NULL). Они такие же?

  3. В части 1 структура включает в себя указатель (p1) и не указатель (p2). В чем разница между свободным указателем, свободным не указателем и свободной комбинацией обоих?

  4. Если я использую delete [] вместо free (). Как? а какая разница?

Ответы [ 2 ]

4 голосов
/ 30 сентября 2019

В части 3, это правильный способ проверить, если (! Params). Любая ошибка здесь не рассматривается?

Да, это правильно, поскольку malloc() возвращает NULL при ошибке.

В части 6 я даю 2 варианта - if (params)) и если (params! = NULL). Они одинаковы?

Да, они одинаковы. Но в C ++ есть несколько причин использовать nullptr (правильный тип nullptr_t) вместо NULL.

В первой части struct содержит указатель (p1) и не указатель (p2),В чем разница между свободным указателем, свободным не указателем и свободной комбинацией обоих?

На самом деле, вы не можете и не можете освободить не указатель. В вашем случае вы освобождаете только один указатель, который является указателем на структуру cipher_params_t. С malloc() вы выделяете память для содержания cipher_params_t независимо от содержимого, вы просто выделяете достаточно места для его хранения. И когда вы free(), вы освобождаете выделенную память, независимо от того, что содержит структура. Обратите внимание, что malloc() и free() не вызывают конструкторы / деструкторы ни для остроконечной структуры, ни для ее содержимого. Они просто резервируют / выделяют пространство памяти.

Если я использую delete [] вместо free (). Как? а какая разница?

Никогда не смешивайте malloc() / free(), new / delete и new[] / delete[], потому что они не делают одно и то же. Вы должны прочитать В чем разница между new / delete и malloc / free? для получения дополнительной информации.

1 голос
/ 30 сентября 2019

По вопросу:

В части 1 структура включает в себя указатель (p1) и не указатель (p2). В чем разница между свободным указателем, свободным не указателем и свободной комбинацией обоих?

в приведенном вами примере вы удаляете структуру из памяти кучи. Эта структура имеет указатель (в предположении 8 байтов) и int (обычно 4 байта), поэтому вы удаляете этот фрагмент памяти (12 байт) и ничего больше.

Память, на которую указывает указатель, останется там,поэтому клавиша [16] не будет затронута. В вашем примере есть возможная проблема, поскольку params находится в куче, а key в стеке, стек будет удален, когда вы покидаете область действия, но указатель params все еще может указывать на него.

...