0

I'm reading to brush up on C++ knowledge that is almost 2 decades old in order to understand online info on the factory pattern. The final usage context will likely be in a different 3rd generation language (3GL), but because of my past experience, I think it's easier to follow C++ than (say) Java, even though the latter may be less intricate in syntax. A bigger reason, however, is that the only code example I can find of the problem being addressed, i.e., in the absence of the factory pattern, is in C++. Most posts talk about the reasons for the pattern in high level narrative, then provide code to show the mechanics of the pattern instead of the problem in the absence of the pattern.

The code I'm studying is located here. I'm having trouble making sense of the fact that delete[] is used to destroy objects that are created using new. According to various readings, delete is used with new, and delete[] is used with new[]. After so long away from C++, however, I could quite easily be overlooking something obvious. Is the cited code OK, or am I right?

My readings on new and delete are:

user2153235
  • 234
  • 1
  • 8
  • 3
    You are correct. That article is incorrect, and is UB – ChrisMM Apr 06 '20 at 16:57
  • 1
    To be honest, you don't want to use either. See [Why should C++ programmers minimize use of 'new'?](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new) – user4581301 Apr 06 '20 at 16:57
  • 3
    Geeks for Geeks is a terribad website. I recommend avoiding it. (Unless your learning style is best served by some authority presenting erroneous information and buggy code, and then you learn by figuring out where they are misinforming you. Then I suppose it's a good site.) – Eljay Apr 06 '20 at 16:58
  • 2
    One of the first things `delete` and `delete[]` do is test for null. That makes most of the code in the `Client` destructor nigh-useless. – user4581301 Apr 06 '20 at 17:00
  • 2
    As for Geeks for Geeks, read their explanation of some algorithm, which is usually ok. Then throw away the code they show you that implements the algorithm. – PaulMcKenzie Apr 06 '20 at 17:04
  • 1
    @user4581301 Only if you desire segmentation faults when a double delete is attempted. – sweenish Apr 06 '20 at 17:05
  • 3
    @sweenish, if you're in the destructor twice you're already hosed on that front. – user4581301 Apr 06 '20 at 17:06
  • 1
    @user4581301 Less about being in the destructor twice, more about receiving an object that invoked the else clause of the constructor (or the Create() function). Since NULL is a valid state, it has to be checked before deleting. – sweenish Apr 06 '20 at 17:08
  • 4
    @sweenish There is never a need to check for null before deleting. Deleting null has no effect. It will never segfault. – eerorika Apr 06 '20 at 17:12
  • Thank you. I agree that the quality of the narrative explanation can be problematic at the cited site, but as I said, no other code illustrates an example of what the problem is in the absence of a factory. In fact, the cited site doesn't quite do that either, I'm finding out, and I will post a separate question about that. – user2153235 Apr 06 '20 at 17:16
  • @eerorika Turns out my life has been a lie. Tried some code out and it didn't segfault. But I'm having difficulties triggering a double delete segfault on godbolt right now, too. – sweenish Apr 06 '20 at 17:21
  • 2
    @sweenish [Here's the standard's take](https://eel.is/c++draft/expr.delete#7) – HTNW Apr 06 '20 at 17:30

1 Answers1

1

Isn't delete[] the counterpart to new[]?

Yes.

delete is used with new, and delete[] is used with new[]

Correct.

Although to be pedantic, delete[] is for deleting arrays. new T[] always allocates an array, but new T can also allocate an array if T is an array type. But this corner case does not apply to the linked article. The article has undefined behaviour.


That's not even where the bugs in the article end. There is more. For example, the behaviour deleting through a pointer to Vehicle that points to a base sub object of a derived object is undefined because the destructor of Vehicle is non-virtual.

Furthermore, Client is copyable, but its copy constructor and assignment operator violate the class invariant of uniqueness that is necessary for the destructor to be valid.

eerorika
  • 181,943
  • 10
  • 144
  • 256
  • Some of the later details in your answer is beyond my nacent C++ revival, but thanks for the warning. I will attempt to parse, but keeping in mind that I only need a conceptual understanding of the factory pattern to follow documentation of an API between a 4GL and a 3GL. Thanks. – user2153235 Apr 06 '20 at 17:19
  • 1
    @user2153235 That means that the use of `new` is beyond your understanding for now. That's OK, its use is an advanced concept. I suggest acquainting yourself with RAII. – eerorika Apr 06 '20 at 17:22
  • 1
    @user2153235 Whenever you encounter an example using `new` for something you search (such as factory pattern), repeat the search but add "smart pointer" to they query. That should usually lead you to a modern (post C++11) solution. – eerorika Apr 06 '20 at 17:25
  • I'm OK overlooking the intricate memory management issues that are specific to C++. I was more trying to find a realistic use case in which the need for a factory can't be trivially circumvented. Still composing the separate question for that. Thanks. – user2153235 Apr 06 '20 at 17:29