Почему 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();