Bad Advices

Pages: 123... 5
closed account (S6k9GNh0)
Some things I really don't like about C++ is some of the rather redundant things I see people suggest to people who are new.

It's a static-length array, not a variable-length array... it matters
Not every single array should be a vector. Hell, there's even std::array meant for static-length arrays. Stop suggesting vector for everything.

A shared pointer is just as hazardous as a raw pointer
I cannot stand shared_ptr. In most cases, it did nothing but add cycles to my program since I was able to design the needed for reference-counted resources out. It is not a replacement for proper memory management in any case, especially in a deterministic environment. Exceptions, of course, would be like C API wrappers... or an environment where memory management isn't of super high concern. It's of my serious belief that shared_ptr can be just as dangerous, if not more in some cases, than a raw pointer. All of other *_ptr have different purposes (except weak_ptr but for a different time).

I can understand the point of these pointers (pun not intended) if there were areas of code that try to escape the area of determinism. Exceptions and error handling in general are a huge part of this. But I don't see where shared_ptr fits into all. It's inefficient, it doesn't always do its job like most people would expect (i.e. having to go out of your way to make sure the last reference is actually the last reference), and so on. You can determine whether something is still using a pointer before you even compile or perhaps using a debugger, something you'd have to use anyways if you a shared_ptr incorrectly.
Last edited on
It's a static-length array, not a variable-length array... it matters
Not every single array should be a vector. Hell, there's even std::array meant for static-length arrays. Stop suggesting vector for everything.
I only use vectors for things that need a variable length.
Not every single array should be a vector.

I agree, char arrays should be std::string. Unless of course you have a problem with that as well.

A suggestion to use std::vector instead of a plain array is by its nature a suggestion that is directed at a beginner. Why should we not suggest std::vector?
closed account (3qX21hU5)
I believe what he is saying is that there is no one sized fits all container in c++. A vector is not best solution for every situation and beginners should learn to know the pros and cons of each of the containers and pick the one that is most appropriate for each situation.

Last edited on
Not every single array should be a vector.


Strongly agree. Nothing wrong with a good old normal array when the situation calls for it.

A shared pointer is just as hazardous as a raw pointer


Disagree. I agree somewhat... but not in the way you intended.

But to really address this... let's bring up another point first...

Every dynamic allocation should be wrapped in some kind of RAII container. Exceptions to this rule exist but are extremely rare. Manual cleanup is extremely error prone, especially in cases where your logic might get unexpectedly interrupted by an exception. And when you screw it up and leak memory, it's very difficult to track down and find. RAII makes it all but full proof.

With that in mind... whether or not shared_ptr is the right pointer for the job is the real question. Usually it isn't. Usually unique_ptr is better (also note: there is no performance penalty with unique_ptr... so there's literally no reason not to use it).


You are correct that smart pointers are not a replacement for proper memory management. It just makes memory management easier. As the developer, you still need to decide who owns what objects. Putting everything in a shared_ptr does not relieve you of that responsibility... and yes.. if you do that... it is possible you'll screw up and leak memory (though I wouldn't call it "more hazardous" by any stretch of the imagination).

shared_ptr should be used when ownership of an object is shared between 2 or more areas of code... or when you need a weak pointer to the objects elsewhere. Neither of these are as common as widely thought.. which is why unique_ptr is usually the better option.
closed account (Dy7SLyTq)
I believe what he is saying is that there is no one sized fits all container in c++.

>:) boost.any (im just messing with you here though. i know what you meant).
closed account (S6k9GNh0)
I do not recall a unique_ptr being viable in a situation where an instance of something may have multiple things holding a reference to it. shared_ptr only does this by reference counter.

e.g. whenever you pass back a shared_ptr, it adds to the counter and then subtracts from the counter whenever that variable that was kept in function scope dies. Thus the counter is still 1 and it is not deallocated.

But unique_ptr (which only allows one holder (hence "unique")) would deallocate regardless of counter since it doesn't even have one. Part of the magic as to why it has no overhead at all.

I just don't like reference counting, especially if it takes advantage of RAII as it's not always obvious as to when a reference is kept alive or dies.
Last edited on
I do not recall a unique_ptr being viable in a situation where an instance of something may have multiple things holding a reference to it. shared_ptr only does this by reference counter.


It's viable as long as the lifetime is known.

1
2
3
4
5
6
7
8
9
10
11
unique_ptr<int> the_owner( new int );

int* some_reference = the_owner.get();

// or

unique_ptr<int>& some_ref = the_owner;

// or

unique_ptr<int>* some_ref = &the_owner;


This is perfectly acceptable as long as it's known that the owner will out-live the reference. This is pretty much an identical situation to any situation where you'd use raw pointers. The only difference is it's impossible to forget the cleanup.

EDIT: though note that this is a bad idea unless you are SURE the lifetime of the owner will ALWAYS exceed the lifetime of the reference. In practice this is very hard to guarantee... which is why it's generally a bad idea to hang on to pointers/references to objects which are owned elsewhere. Pass them as parameters when needed and then ditch them. /EDIT


If the lifetime of this is not known... then yes... unique_ptr is not appropriate (but neither are raw pointers), and shared_ptr+weak_ptr would be safer.


I just don't like reference counting, even if it takes advantage of RAII as it's not always obvious as to when a reference is kept alive or dies.


That's not shared_ptr's problem... that's your code being sloppy's problem.

Like I said... shared_ptr is not an excuse to avoid the responsibilities of memory management. If your code doesn't have clear ownership of dynamically allocated objects, with clearly defined lifecycles... then it's messy code. Simply throwing in smart pointers everywhere doesn't clean the mess.
Last edited on
Not every single array should be a vector

Vectors are just the simplest and the most versatile containers. If you found a reason to use an array instead a vector in some particular case, it's fine, that's the appropriate sequence (start with generic, then specialize).
Note that fixed size alone is not the reason to always replace vectors with arrays - algorithms that involve swapping or moving those fixed-size containers would get killed.

i cannot stand shared_ptr

I like it quite a bit, it has some awesome features, but I've only willingly used it once in production so far (it was called boost::shared_ptr then). It is very hard to come by a valid design that involves shared ownership. I agree that adivising shared_ptr for any sort of "memory management" is usually wrong (and smells of Java)
/s/full proof/foolproof
closed account (S6k9GNh0)
With the idea that a shared_ptr can be misused if you're code is sloppy was one of the reasons to dynamically manage memory, so the user wouldn't have to. People complain all of the time that even though a program's logic is deterministic, it is bound to leak because of the programmer's flaws without automated help.

So, how do you say that you shouldn't abuse a shared_ptr with sloppy code... but then turn around and say that using a raw pointer is bad as it's dangerous with sloppy code?

I see hypocrisy. shared_ptr might help when it comes to invalidating pointers before you have a chance to free them. But again, the opposite (not deallocating memory because a reference still exists when it shouldn't) still exists and there is no wrapper around that.

EDIT: That and a shared_ptr wastes resources when it might not have too.
Last edited on
I've never yet had a use for shared_ptr. I use unique_ptr and non-owning raw pointers a lot. I can envision how it could be useful for certain types of problems though.

Also I've not been exposed to any bad advice regarding usage of shared_ptr (that I am aware of).
computerquip wrote:
It's a static-length array, not a variable-length array... it matters
Not every single array should be a vector. Hell, there's even std::array meant for static-length arrays. Stop suggesting vector for everything.
I have not yet encountered a time where I needed a static length array, could you give an example? Obviously std::array was invented for a reason but it must be rare for what I do.
Last edited on
closed account (S6k9GNh0)
uh, a table and a network/audio buffer off the top of my head.

EDIT: You do also realize that each time a vector/string has to be reallocated, it's really slow right? It's not something you want happening constantly.

EDIT: Text files and 3D models come to mind (as I load some GLSL shaders).
Last edited on
closed account (3qX21hU5)
I have not yet encountered a time where I needed a static length array, could you give an example? Obviously std::array was invented for a reason but it must be rare for what I do.


Variable length arrays have a larger performance impact then static length arrays so generally you should use them when it is possible (IE you know what the maximum size of the container will be).

Static-length arrays are used quite commonly in game development instead of dynamic-length arrays like vector since they don't have the added cost of due to reallocation and data copying among other things.

Also dynamic memory allocation is actually a quite slow operation.

But you are right most of the time you could use a dynamic-length array in the place of a static-length array and get by just fine, but what I believe computerquip is saying is that just because it works doesn't mean it is the best container for the job.
So, how do you say that you shouldn't abuse a shared_ptr with sloppy code... but then turn around and say that using a raw pointer is bad as it's dangerous with sloppy code?


shared_ptr leaks if you have circular ownership. IE, classA has a shared_ptr to classB and vice versa.

Raw pointers suffer from that problem, plus 4 other problems:
1) risk forgetting to delete
2) risk of dereferencing pointer after the object has been deleted
3) risk of exception causing the delete to be skipped
4) risk of object being deleted multiple times.

Starts as thread about bad advice being given to beginners.

Later brings up performance and efficiency as arguments for why suggesting the easier approach is bad.
closed account (S6k9GNh0)
shared_ptr does not really fix #3 or #1.

#3 can be fixed with a unique_ptr.

#1 is only half fixed given that you'll have to figure out whether every reference is dead in order to ascertain that it's deleted.

#2 and #4 are the same problem in different scenarios (dangling pointers).

#4 can easily be fixed by setting the pointer to NULL after deletion which can be wrapped in a macro/function instead of using unsafe delete. If different resources hold the same pointer (meaning one does not hold a reference of another pointer, but a true copy of the pointer) then that is "bad design". Holding a reference to another pointer and using a function rather than delete will prevent deleting that pointer and require you leave it up to whatever owns that pointer to delete it, at the cost of nothing.

Thus, I believe #2 is the only part of which shared_ptr truly "fixes" but at the cost of a counter.
closed account (S6k9GNh0)
@ Catfish4, one is not easier over the other nor did I ever say that. C++ isn't a language for beginners but telling someone they should do something that is probably bad practice doesn't help.
@computerquip

I don't see your problem with shared_ptr. what you describe under #4 is exactly the task of the shared_ptr. It cannot be fixed easily otherwise.
sharing a pointer is not a bad design if you can do that without a risk

#1 is fully fixed. The pointer is deleted when all variables that hold a copy of the pointer are out of scope and completely unreachable within the entire program

The reference count is a problem that appears when a pointer is assigned. But if that happens too often you did something majorly wrong.
Plus you can use freely the raw pointer within a function without the fear that it's deleted while you're using it if it's passed as a shared_ptr
Pages: 123... 5