Как мне правильно использовать sizeof для измерения блока в malloc?

#c #pointers #struct #malloc #sizeof

#c #указатели #структура #malloc #sizeof

Вопрос:

Предположим, у меня есть простая структура, включающая несколько указателей:

 typedef struct Type {
    uint32_t* intArrayPointer;
} Type;
 

Каков правильный способ для malloc указателя структуры? Поскольку работают оба способа, я предполагаю, что один из двух выделяет больше памяти, чем необходимо:

  1.   Type* newType() {
         Type* returnPointer = malloc(sizeof(Type));
         returnPointer->intArrayPointer = malloc(sizeof(uint32_t)*128);
         return returnPointer;
     }
     
  2.   Type* newType() {
         Type* returnPointer = malloc(sizeof(Type*));
         returnPointer->intArrayPointer = malloc(sizeof(uint32_t)*128);
         return returnPointer;
     }
    
     

Для справки, как это будет использоваться в коде:

 void freeType(Type* this) {
    free(this->intArrayPointer);
    free(this);
}

int main() {
    Type* pt = newType();
    //do Stuff
    freeType(pt);
}
 

Комментарии:

1. sizeof(Type*) может быть больше, меньше или равно sizeof(Type) . Ключевым моментом является то, что это неправильно.

Ответ №1:

Лучшим способом было бы использовать

 Type* returnPointer = malloc(sizeof(*returnPointer));
 

или, лучше,

 Type* returnPointer = malloc(sizeof *returnPointer); 
            // parenthesis is needed only when argument is a type, 
            // not needed for expressions used as argument
 

который вообще не зависит от типа.

Точно так же и вы должны делать intArrayPointer то же самое. И не забудьте также проверить успешность вызовов.

Комментарии:

1. С intArrayPointer помощью я действительно хочу зарезервировать 512 непрерывных байт, при этом указатель указывает на первый.

2. @WhozCraig очень актуально, позвольте мне добавить это.

3. @FrankPirata Все в порядке, я говорю только о синтаксисе.

4. Минор: sizeof *returnPointer с пробелом меньше похоже на умножение, чем sizeof*returnPointer .