Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

How do you prefer to use e.g. malloc?


Please see https://stackoverflow.com/questions/605845/do-i-cast-the-res... for some thoughts on this.

In short (as already stated, of course), you don't need to cast void * in C to/from other object pointers. Adding a cast to the return value of malloc() is a bad idea (I'm biased).


You don't need to cast there... malloc returns a void*.


Which you are going to use how? Don't you have to cast it to something to be able to use it?


No, you don't. The following,

    int *i = malloc(sizeof(int));
is valid C, and will compile just fine. I think it's considered good form, too, as the cast doesn't really add anything not already present, and might even drift out of date with the surrounding code. (And just gets in the way of legibility.)

IIRC, it is not valid C++. But malloc()/void * is somewhat rarer to find there, as you have better options.


That's an implicit cast from void * to int * .

    void *malloc(size_t size);


In standard parlance, that is a conversion. Only (this) is a cast.


There's no such thing as an "implicit cast". A cast is an explicit conversion (a cast expression), and the assignment expression discussed here has an implicit conversion.


you mean `mmap`?

Also yes I'm radical enough to suggest the 50+ year old C standard library API is bad. Which isn't really a radical position >.>


mmap and malloc do very different things. You didn't really clarify why you thought malloc() was bad, or why you think someone should call mmap(), so I'm mostly left to guess.

mmap, for example, is free to require that the requested range be a multiple of a page; trying to use it as if it were malloc() would, on such systems, cause any allocations less than a page to require a whole page. And since this is a rather common case, you'd be using a ton more memory.

malloc(), however, can subdivide a large allocation from the OS into small allocations for the process; it is my understanding that most modern malloc()s will do this, in some form. (It is also my understanding that some malloc() implementations will use mmap() for allocating memory from the OS…)


`malloc` is part of the standard library. the underlying implementation is environmental specific, or implementation specific depending on the host application.

Generally speaking `mmap` is the system call that

* Allocates memory

* Moves allocations around

`malloc` is the common entry point into a library that attempts to ensure you invoke the `mmap` system call as little as possible.

   trying to use it as if it were malloc() would, on such systems,
   cause any allocations less than a page to require a whole page.
   And since this is a rather common case, you'd be using a ton more
   memory.
This is a misconception [1]. Malloc is governed by hardware limitations. If you ask for 50bytes, it'll give you a full 4KiB page, because hardware can only segment memory in 4KiB chunks. Actually some allocators will attempt to _use_ those non-allocated regions of the remaining ~4046 bytes for other allocations in order to be faster (less systemcalls), this is why sometimes writing past buffer ends can give you garbage data instead of segfaults.

[1] https://stackoverflow.com/questions/45458732/how-are-memory-...


The link you post is about mmap; the section you quote is about malloc. The link is correct — about mmap; but that limitation does not apply to malloc. The link precisely backs up the part you're quoting, so saying "This is a misconception" makes no sense.

> If you ask for 50bytes, it'll give you a full 4KiB page, because hardware can only segment memory in 4KiB chunks.

No, not really. (But you seem to realize this, as you contradict this point in the next quote I'll pull.) A malloc implementation is free to divvy up a page in order to service several allocations. Just because the pointer it returns to you is somewhere within a page that must, almost by definition, be a full page is irrelevant to the point of this discussion (that malloc() is not needed b/c mmap exists, and is somehow superior). The point is that the allocation consumes, in the grand scale of things, an amount on par with the requested size. (There is some overhead, of course, but not nearly the same are the mmap-must-return-a-full-page overhead.)

> Actually some allocators will attempt to _use_ those non-allocated regions of the remaining ~4046 bytes for other allocations in order to be faster (less systemcalls), this is why sometimes writing past buffer ends can give you garbage data instead of segfaults.

That was part of the point I was making.

You seem to have misunderstood my post. malloc() is free to divvy up a page (potentially handed to it by mmap) into several allocations. mmap() cannot. The point here is that replacing every malloc() call with a call to mmap() results in the loss of that ability to divvy up pages, requiring each allocation to be a full page; this would significantly bloat the memory consumed by an application, as small allocations would not share pages. Hence why those two calls are not equivalent, which is what the original post:

> you mean `mmap`?

> Also yes I'm radical enough to suggest the 50+ year old C standard library API is bad.

Very much seemed to imply. Though, again, I asked for clarification on your point, to make sure I'm understanding it, and you again failed to provide it. So, again,

> You didn't really clarify why you thought malloc() was bad, or why you think someone should call mmap() [in lieu of malloc()], so I'm mostly left to guess.


    A malloc implementation is free to divvy up a page in
    order to service several allocations
But like the hardware won't enforce that. So yeah you can malloc 50bytes, but the hardware is just going to assume there is a 4096 based page behind it. Because what memory can/cannot be written/read too is controlled by mmap -> linux -> hardware MMU.

So when ever `malloc` gives you 50bytes without allocating an entire page it's just lying to you and giving you a pointer offset from another allocation. This isn't strictly being enforced by anything. There is zero contract that enforces what memory you can/cannot use.


> There is zero contract that enforces what memory you can/cannot use.

There is, though; malloc's specification forms a contract. You are not allowed to access outside the bounds of the returned pointer. That some hardware allows it sometimes does not mean that there is "zero contract".

The function represents an interface, and an interface is a set of rules and behavior both the user & consumer of that interface expect. If you stray from that, it's UB, and the machine can do whatever at that point.

In this case, that's what matters. We don't know what hardware malloc or mmap will run on, and it isn't impossible that someone could implement a malloc() implementation that did enforce those bounds. valgrind, for example, is very close to this: it already knows when you access memory outside of the bounds of a malloc'd region (as that's its purpose: to report such accesses), and it would be a trivial modification to it to kill the program on an illegal access.


Is your irritation aimed at the implementations of malloc in the standard compilers? Or all malloc implementations? (e.g. Hoard [0]).

[0] https://github.com/emeryberger/Hoard


my irritation is C's primitive type system. And programmers willingness to conflate their standard library with system level operations.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: