7 ms·
The example given: char *buf = new char[s](); Put into Compiler Explorer: https://gcc.godbolt.org/z/QAs9gz However, doing this is a very strong code
by inetknght 7y ago
The example given:
char *buf = new char[s]();
Put into Compiler Explorer:
https://gcc.godbolt.org/z/QAs9gz
However, doing this is a very strong code smell. At the very least, using `new` and assigning to a raw pointer is a sign that the C++ developer is managing memory manually and is likely to hit a lot of problems including memory leaks or segmentation faults. Also many would forget that this is calling `operator new[]()`, not `operator new()` and might confuse with placement-new `operator new(...)` or `operator new[](...)`. And the developer might also forget that `new` could throw an exception... [0]
The developer should instead be using, at a minimum, a `std::unique_ptr<char[]>` [1]. Or, IMO, a `std::vector<char>` which reminds the developer not only of the pointer but also of the count of bytes which have been allocated (.capacity()) and also of the valid range which has been initialized (.size()).
IMO, if the developer wanted a pointer to a byte array then it's a lot easier to use `malloc()` than trying to remember all the different ways you can get screwed by `operator new`:
std::unique_ptr<char, std::function<void(char*)>> m{
(char*)std::malloc(count), std::free
};
[0]: https://en.cppreference.com/w/cpp/language/new https://en.cppreference.com/w/cpp/language/new
[1]: https://en.cppreference.com/w/cpp/memory/unique_ptr https://en.cppreference.com/w/cpp/memory/unique_ptr
- burfog 7y agoI gave up on C++ in part because the language changes too much. I paid for lessons on it. The std:: stuff didn't exist, templates were a recent invention, and people were starting to agree that putting the overload keyword everywhere was bad style. Mostly, people were just excited about // comments and cout. I keep hearing about how C++ is supposed to be done, and it seems to change every year. I don't know what people do with the older code as it becomes unfashionable with "very strong code smell". Updating it is risky busywork, kind of like porting to Python 3, with potential for serious bugs. Leaving it in place will make developers differently unhappy. It isn't easy getting everybody on a team to agree on what subset of C++ is OK to use. People will sneak in their must-have feature. You'd have better luck getting agreement between emacs and vi.
- ncmncm 7y agoC++ makes no pretense of ever planning to be "done". "Done" is another word for dead. Even COBOL is still evolving. Failing to keep up with evolving languages is called stagnation. Everyone is free to stagnate, but I do not advise it. You use the subset of the language supported by the compiler you have. Code using newer features is better because the new features were added for sound engineering reasons, not just to be different.
- lmm 7y agoIt's the opposite of sound engineering. Every version of C++ contains a new feature that does 11% of the proper solution because the feature in the last version only did 9% of the proper solution. Despite all that churn the language is still as far behind ML as ever.
- ncmncm 7y agoI see that you have not been keeping up.
- throwaway17_17 7y agoWhat has the parent comment not keeping up with? Was it a reference to the ‘11%’ or to C++ being ‘behind ML’? Just curious to see what your objection was.
- ncmncm 7y ago11%
- PaulDavisThe1st 7y agoIf you think C++ changes too much, you're going to love today's Java/Typescript flavor-of-the-month web UI toolkit.
- pjmlp 7y agoYes it is hard to keep up, but so it is like any other language with mainstream usage. Languages either evolve to fulfill market needs or they die. Even C17 has plenty of differences down to K&R, not counting all the compiler specific extensions.
- unlinked_dll 7y agoEh I'd say using malloc in place of new is more code smell than anything here. If you want a byte array make a byte array std::make_unique<std:::array<char, SIZE>>() If you don't know how big you want the byte array make a vector. std::vector<char>(size) It's baffling to me how many C++ developers don't use the standard collections. The only one that really sucks is unordered_map.
- ipmifatwa 7y agostd::list sucks at least as much as std::unordered_map.
- mgraczyk 7y agovector<bool> also sucks
- unlinked_dll 7y agoThat's fair. But in my experience that's rather rare and easy to work around.
- vardump 7y agoSmall vectors are also bad. There should be some kind of small vector optimization, just like what is common for std::string.
- ipmifatwa 7y agoSometimes your just need a buffer for a syscall. Newing a buffer is canonical and unique_ptr isn’t free enough to use in the most performance sensitive contexts.
- a_t48 7y agoCan you give an example of unique_ptr being too heavy?
- fnbr 7y agoI worked with a team which used raw pointers instead of unique_ptr as they use more memory (twice as much, I think). The core data structure was a tree, and the tree was several hundred GB in size. So they were doing whatever they could to shave off memory.
- de_watcher 7y agoWithout a custom deleter unique_ptr should have zero overhead.
- likeliv 7y agounique_ptr does not have any memory overhead. (unless you use a custom deleter, but even then you could use one which does not use memory)
- tcbawo 7y agoUnique pointers imply ownership of the underlying memory. If you have multiple references to the same data, or in your case a tree, it might make sense to use raw pointers (or references) to access the tree data. It would not make sense to grant ownership of the same memory to two unique_ptr, or make copies of data unnecessarily.
- inetknght 7y agoIn that case, you'd have something like `std::vector` or `std::unique_ptr` which owns the actual allocation (and governs the scoping and therefore deallocation), while using `vector.data()` or `unique_ptr.get()` to pass around an unowned pointer. All raw pointers can then be considered to be unowned by convention.
- dmitrygr 7y ago> using `new` and assigning to a raw pointer is a sign that the C++ developer is managing memory manually and is likely to hit a lot of problems including memory leaks There is no need to badmouth all c++ developers. Plenty of us can keep our memory straight just fine. just because you don't like pointers, does not mean the rest of us can't use them perfectly safely.
- pjmlp 7y agoThe rest of us isn't that big number according to Microsoft and Google security reports. I surely have my share of C++ pointer mistakes done since I got hold of C++ARM and Turbo C++, after years of Assembly and Turbo Pascal programming. Not only C++, but any other language with manual memory management, because keeping track of where everything is going manually, just doesn't scale.
- asdfasgasdgasdg 7y agoI think the evidence is pretty clear that programmers can't, in general, use bare pointers properly. The very best write use after free, double free, stack smashers, and all manner of other memory related bugs. We can see the evidence of this fact in the CVEs, the syzkaller bugs, etc. If you haven't been bitten by a serious instance of one of these, then you just haven't written very much C++. IMO the debate about whether programmers can safely handle bare pointers is over. They can't. The only question is whether smart pointers help enough to make the extra line noise worth it.
- choeger 7y agoAnd the guys that implement smart pointers are what, exactly? Uberprogrammers? Is there a certificate to get into that club? What about compiler authors, that deal with, gasp, optimizations of these bare pointers? Kernel developers? Embedded system engineers? It is ok to stay above a certain level of abstractions consciously, but stating that one cannot go below safely is just steadying mediocrity.
- lmm 7y ago
- X-Istence 7y agoThis is one of the best troll posts that is getting taken seriously ever... wow.
- SamReidHughes 7y agoThe std::function<void(char*)> is the tell :-)
- inetknght 7y agoWhy do you think that marks a troll? Have you never had to use a C library which wants you to use the library's structure allocator / deallocator? In that case, this translates very well to malloc/dealloc. @unlinked_dll has it correct: the C++ way to allocate an array of chars is `std::vector<char>` (or `std::array<char, size>`).
- SamReidHughes 7y agoIt's a bit bloaty and verbose as well, you could just use void(&)(void *).
- gurkendoktor 7y agoDoesn't that break when std::free does not have the default C++ calling convention? I think `decltype(std::free)` would be easier to read anyway, but writing a deleter class that calls std::free in its operator() has the advantage that it will not use any memory in the unique_ptr thanks to the empty base class optimization.
- SamReidHughes 7y agoI don't think that's possible, and in that case the std::function wouldn't work either.
- gurkendoktor 7y ago