Почему calloc требует два параметра, а malloc - один?

Мне очень надоело писать calloc(1, sizeof(MyStruct)) все время. Я не хочу использовать идею, как обертывание этого метода и т.д. Я имею в виду, что я хочу знать, что мне дают два параметра? Если он что-то дает, почему malloc не имеет двух параметров?

Кстати, я искал ответ на этот вопрос, но я не нашел действительно хорошего ответа. Эти ответы заключались в том, что calloc может выделять более крупные блоки, чем malloc can и т.д.

Я увидел еще один ответ, что calloc выделяет массив. С malloc я могу размножаться, и я получу массив, и я могу использовать его без 1, в начале.

Ответы

Ответ 1

Исторические причины.

В момент ввода calloc функция malloc не существовала, а функция calloc обеспечивала правильное выравнивание для одного элемента элемента.

Когда после этого было введено malloc, было решено, что возвращенная память будет правильно выровнена для любого использования (что потребует больше памяти), и поэтому нужен только один параметр. API для calloc не был изменен, но calloc теперь также возвращает правильную выровненную память для любого использования.

EDIT:

См. обсуждение в комментариях и интересный ввод @JimBalter.

Мое первое утверждение о введении malloc и calloc может быть абсолютно неправильным.

Также реальные причины также могут быть не связаны с выравниванием. История C была сильно изменена разработчиками компилятора. malloc и calloc могут исходить от разных исполнителей/компиляторов, и это объясняет разницу API. И я действительно одобряю это объяснение как настоящую причину.

Ответ 2

Единственная причина, по которой я мог придумать, - это

int *foo = calloc(42, sizeof *foo);

- один символ короче

int *foo = malloc(42 * sizeof *foo);

Настоящая причина, по-видимому, потеряна для десятилетий истории C > тысячелетий и нуждается в археологе языка программирования, чтобы раскопать, но может быть связана со следующим фактом:

В отличие от malloc() - который должен вернуть блок памяти, выровненный в соответствии с полным размером блока, - при использовании calloc(), как предполагалось, блок памяти нужно будет только выровнять в соответствии с размером, переданным как второй аргумент. Однако стандарт C запрещает эту оптимизацию в соответствующих реализациях.

Ответ 3

calloc выделяет массив элементов в памяти, размер Число элементов (первый параметр) умножает размер элемента на выделение определенного количества (второго параметра). Кроме того, calloc инициализирует этот массив равным 0. Размер элемента может быть больше байта, и функция вычисляет необходимый размер памяти для вас.

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

Обе функции по сути дают вам ту же функциональность.

Здесь ссылки:

malloc calloc

Ответ 4

это просто по дизайну.

вы можете написать свой собственный calloc

void *mycalloc(size_t num, size_t size)
{
    void *block = malloc(num * size);
    if(block != NULL)
        memset(block, 0, num * size);
    return block;
}

Ответ 5

Вы не должны выделять объекты с помощью calloc (или malloc или что-то в этом роде). Даже несмотря на то, что calloc zero инициализирует его, объект все еще не был сконструирован с учетом С++. Для этого используйте конструкторы:

class MyClass
{
private:
    short m_a;
    int m_b;
    long m_c;
    float m_d;

public:
    MyClass() : m_a(0), m_b(0), m_c(0), m_d(0.0) {}
};

И затем создайте экземпляр с помощью new (или в стеке, если сможете):

MyClass* mc = new MyClass();