22

It's very bothersome for me to write calloc(1, sizeof(MyStruct)) all the time. I don't want to use an idea like wrapping this method and etc. I mean I want to know what two parameters gives me? If it gives something, why doesn't mallochave two parameters too?

By the way, I searched for an answer to this question but I didn't find a really good answer. Those answers was that calloc can allocate larger blocks than malloc can and etc.

I saw another answer that calloc allocates an array. With malloc I can multiply and I'll get an array and I can use it without 1, at the start.

DividedByZero
  • 421
  • 1
  • 5
  • 11
  • 1
    Because `calloc` allocate a zeroed array of elements of the same size, while `malloc` allocate an uninitialized heap zone. – Basile Starynkevitch Sep 23 '12 at 20:19
  • 2
    Possible duplicate of http://stackoverflow.com/questions/4083916/two-arguments-to-calloc – gtgaxiola Sep 23 '12 at 20:19
  • @gtgaxiola I saw that answer. It's with the larger blocks. It's not what I asked for :(. – DividedByZero Sep 23 '12 at 20:21
  • 2
    @BasileStarynkevitch That's no reason for two parameters, a simple size in bytes (like malloc) would be enough to zero the memory. – Eloff Sep 23 '12 at 20:21
  • This is a duplicate question that has been asked several times before, e.g., http://stackoverflow.com/questions/4083916/two-arguments-to-calloc and http://stackoverflow.com/questions/7581192/how-did-malloc-and-calloc-end-up-with-different-signatures – Jim Balter Sep 23 '12 at 20:40
  • @JimBalter Those questions didn't got really answer. (Read all of the text of the question) – DividedByZero Sep 23 '12 at 20:45
  • @DividedByZero The fact that you didn't find what you consider a good answer doesn't change the fact that the questions are duplicates. – Jim Balter Sep 23 '12 at 21:36
  • @JimBalter When there is no good version for something ,we making new and a better version and replace it with that something. – DividedByZero Sep 23 '12 at 22:34

4 Answers4

29

Historical reasons.

At the time of when calloc was introduced, the malloc function didn't exist and the calloc function would provide the correct alignment for one element object.

When malloc was introduced afterwards, it was decided the memory returned would be properly aligned for any use (which costs more memory) and so only one parameter was necessary. The API for calloc was not changed but calloc now also returns memory properly aligned for any use.

EDIT:

See the discussion in the comments and the interesting input from @JimBalter.

My first statement regarding the introduction of malloc and calloc may be totally wrong.

Also the real reasons could also be well unrelated to alignment. C history has been changed a lot by compiler implementers. malloc and calloc could come from different groups / compilers implementers and this would explain the API difference. And I actually favor this explanation as the real reason.

Community
  • 1
  • 1
ouah
  • 142,963
  • 15
  • 272
  • 331
  • +1 - Wow, answers a question that always burnt in my soul with a (more or less) reasonable explanation. I also didn't know `calloc` was older than `malloc`, as `malloc` seems the more fundamental thing. – Christian Rau Sep 23 '12 at 20:35
  • 2
    Can you please cite a reference for the claim that calloc preceded malloc? I've been programming in C since Bell Labs Unix version 6, and I'm almost certain that this claim is incorrect. – Jim Balter Sep 23 '12 at 20:37
  • @JimBalter There is an explanation in clc in https://groups.google.com/d/msg/comp.lang.c/jZbiyuYqjB4/NIAmeNd11IoJ The poster quotes a paragraph of K&R1 about `calloc` function. The K&R1 paragraph also mentions the existence of an `alloc` function. – ouah Sep 23 '12 at 20:45
  • Your source is wrong; malloc existed long before K&R1 was written in 1978. The alloc function was *pedagogy*, existing only for the sake of explanation in the book; there was never such a function in the C library. – Jim Balter Sep 23 '12 at 20:47
  • @JimBalter Do you have a copy of K&R1? From the source `malloc` was not specified in K&R1. Note that for the `alloc` function I agree you are probably right, there is also an `alloc` example in K&R2. – ouah Sep 23 '12 at 20:55
  • What I have is an apparently faulty memory ... but it's still more accurate than your source. From http://man.cat-v.org/unix-6th/3/ we can see that `alloc` and `free` were in the library, but not `calloc`, and `alloc` only took one argument. Again, K&R1 was *pedagogical*, and was about the C language, not a reference manual for UNIX or the C library. calloc, with its two arguments, was added to UNIX in the Programmer's Workbench (PWB), which came between V6 and V7 (and later became System III), and was found in V7: http://plan9.bell-labs.com/7thEdMan/vol1/man3.bun – Jim Balter Sep 23 '12 at 21:19
  • @JimBalter thank you for the interesting links. I still think the reasons for the API difference between malloc and calloc is because of alignment. I could not see any other valid reasons. Do you have another opinon? – ouah Sep 23 '12 at 21:36
  • 1
    I think the main reason for the difference is that they were designed by different groups. PWB was developed by a group at Bell Labs separate from research, and that introduced some redundancy into the library and the commands. I don't think alignment buys much since the length (or a pointer to the next block) was stored with the allocated memory and it would be painful to manipulate it if it wasn't aligned -- and portability meant that alignment requirement was loose. – Jim Balter Sep 23 '12 at 21:39
  • 1
    +1 Nice. We don't really know, and it's good to acknowledge that. I'm almost inclined to delete my strongly stated but false comment that alloc was never part of the library, but I think I'll leave it, humbled by how sure I was of something that isn't true. – Jim Balter Sep 23 '12 at 22:01
  • 2
    @JimBalter I also wanted to delete my answer but I think it is better if the discussion remains. – ouah Sep 23 '12 at 22:04
  • Another small part of the story is the existence of `cfree` (http://linux.die.net/man/3/cfree). – Jim Balter Sep 23 '12 at 22:09
  • @JimBalter: interesting - the existence of `cfree()` suggests that `calloc()` did not store the metadata about block size... – Christoph Sep 23 '12 at 22:27
  • 1
    Look at http://minnie.tuhs.org/cgi-bin/utree.pl and search for alloc and marvel at what you will discover ... e.g., http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7M/src/libc/gen/calloc.c ("gen" was the PWB library that was an addendum to the C library). – Jim Balter Sep 24 '12 at 00:12
5

The only reason I could come up with is that

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

is one character shorter than

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

The real reason is apparently lost to the millennia centuries decades of C history and needs a programming language archaeologist to unearth, but might be related to the following fact:

In contrast to malloc() - which needs to return a memory block aligned in accordance to the full block size - when using calloc() as intended, the memory block would only need to be aligned in accordance to the size passed as second argument. However, the C standard forbids this optimization in conforming implementations.

Christoph
  • 164,997
  • 36
  • 182
  • 240
  • It's just to allocate memory ,it can't optimize it. If it can then it can optimize it both the allocate methods. – DividedByZero Sep 23 '12 at 22:32
  • 1
    @DividedByZero: say your architectures supports 2-byte and 4-byte alignment; `malloc(6)` will need to return a 4-byte aligned block, whereas `calloc(3, 2)` could return a 2-byte aligned block if not for the restrictions probably introduced when C was standardized – Christoph Sep 23 '12 at 22:39
  • 1
    The C standard (I was on the standards committee, so this one I remember well) came long after malloc and calloc were introduced. And I'm pretty sure that, as of UNIX Version 7, calloc just called malloc and then cleared the memory. – Jim Balter Sep 23 '12 at 23:04
  • @JimBalter: thanks for your clarification; from the link you provided in another comment, it appears that there existed \*nixes where one had to call `cfree()` on blocks allocated via `calloc()` - so at least *someone* needed to come up with the semantics which were later incorporated into the standard; I wouldn't be surprised if this actually happened due to laziness when porting `calloc()` to another *nix variant – Christoph Sep 23 '12 at 23:24
  • 1
    Search for alloc at http://minnie.tuhs.org/cgi-bin/utree.pl and you'll discover a lot of interesting things, like http://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/source/iolib/calloc.c – Jim Balter Sep 24 '12 at 00:09
0

it is just by design.

you could write your own calloc

void *mycalloc(size_t num, size_t size)
{
    void *block = malloc(num * size);
    if(block != NULL)
        memset(block, 0, num * size);
    return block;
}
esskar
  • 10,638
  • 3
  • 36
  • 57
  • 2
    Why was this correct answer downvoted without comment? Such downvotes are bad SO citizenry. – Jim Balter Sep 23 '12 at 20:45
  • @JimBalter Design is not an answer. Programming is not an iPhone and who create this function'll not has a time on designing his functions. – DividedByZero Sep 23 '12 at 21:02
  • @GamecatisToonKrijthe I don't know what your comment means. Answers at SO initially have a vote of 0, and there's an answer below with no downvotes, and an answer above with 2 downvotes. None of the downvotes have been explained nor have the downvoters taken responsibility. – Jim Balter Sep 23 '12 at 21:30
  • @DividedByZero I can't parse your comment, which is not in English. iPhones aren't the only thing designed; programs and APIs are also designed. The answer is correct: one or two arguments is a design choice, nothing more. – Jim Balter Sep 23 '12 at 21:32
  • @JimBalter I mean like adding parameters to it and make it more beautiful. The second parameter is useless and annoying. – DividedByZero Sep 23 '12 at 22:41
  • @DividedByZero that's not what "design" means in programming. And there is no reason to think that there are two parameters to "make it more beautiful". – Jim Balter Sep 23 '12 at 22:43
  • 1
    This calloc is buggy, it's easily vulnerable to overflow. – Karol S May 29 '18 at 14:09
-2

You shouldn't allocate objects with calloc (or malloc or anything like that). Even though calloc zero-initializes it, the object is still hasn't been constructed as far as C++ is concerned. Use constructors for that:

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) {}
};

And then instantiate it with new (or on the stack if you can):

MyClass* mc = new MyClass();
user1610015
  • 6,561
  • 2
  • 15
  • 18
  • 3
    This question is about C not C++. – DividedByZero Sep 23 '12 at 21:00
  • But you said that you were writing `calloc(1, sizeof(MyClass))`, which suggests you're using calloc to allocate objects. If not, what is MyClass then? – user1610015 Sep 23 '12 at 21:09
  • One can do class-oriented programming in C and define things like `typedef struct { /* instance variables */ } MyClass;` – Jim Balter Sep 23 '12 at 21:34
  • @JimBalter That would be a struct (a POD more precisely), not a class in the object-oriented sense. I guess we'll have to hear it from DividedByZero. – user1610015 Sep 23 '12 at 21:47
  • @user1610015 It is a class in the object-oriented sense if it is accompanied by functions like `MyClass_foo(MyClass* this, ...)`. "object-oriented" is a methodology, not a syntax. – Jim Balter Sep 23 '12 at 22:05
  • @JimBalter It may be accompanied by functions, but MyClass still isn't a class because it has no encapsulation and no behavior, just POD (Plain Old Data). – user1610015 Sep 23 '12 at 22:50
  • @user1610015 It doesn't have to have those things to be object-oriented, or to be a class ... but those functions *are* behavior, and encapsulation is achieved by the naming convention. Again, it's about methodology, not syntax. POD is a C++ term, but C++ is not the only arbiter of what "object-oriented" or "class" mean. Anyway, we're way off topic, and I'm done. – Jim Balter Sep 23 '12 at 22:59