-4

I am making a class for dynamiclly allocated variables in c++ mostly for learning. And I ran into a bug, where when I delete the class, calling the deconstructor un-allocating the memory, and than deleteing the class, it seems to delete all my code after that as well, why is this?
Here you have some code from the program:

Destructor:

k_int::~k_int() {
  delete[] Integer;
}

Constructor:

k_int::k_int(int value, bool BooleanConstant = false) {
  Integer = new (nothrow) int[1];
  constant = BooleanConstant; // if you wanna make your allocated space constant
  if (Integer == nullptr) {
    cout << STD_MEM_ERR << endl;
    exit(0);
  }
  Integer[1] = value;
}

Main:

int main() {

  k_int a(123);
  a.print();// I did not show the source code for this
  delete &a;

  cout << "Test after delete" << endl;// Does not run, nothing does :(

}


EDIT: The reason I wanna delete variables is that I don't wanna have them running for the rest of the program, that it won't exist after i close my program does not help.

sladet
  • 43
  • 7
  • 7
    Undefined behavior. Anything can happen. – drescherjm Jul 19 '17 at 19:43
  • 2
    Please format your code properly (indent with four spaces). – user0042 Jul 19 '17 at 19:44
  • 4
    You're using `delete` on something you didn't get from `new` - `a`. Don't do that. And, in general, you should almost never use `delete`. – Alan Stokes Jul 19 '17 at 19:45
  • @AlanStokes Specify more, should i use free() or what? – sladet Jul 19 '17 at 19:47
  • 3
    You should only `delete` what you create with a `new`, that's not the case for object `a`. You don't have to call `delete` on it at all, it will be deleted automatically when it's scope ends. – Havenard Jul 19 '17 at 19:47
  • @sladet You don't need to use anything like `delete` or `free()`. – user0042 Jul 19 '17 at 19:48
  • @sladet Also, when you need to heap-allocate, you still don't need to use `new`; you can use `std::unique_ptr` with `std::make_shared`. Avoiding `new` and `delete` makes it easier to avoid bugs – Justin Jul 19 '17 at 19:48
  • @user0042 Does it just disapear? – sladet Jul 19 '17 at 19:48
  • 3
    Also, `Integer[1] = value` is out of bounds. – molbdnilo Jul 19 '17 at 19:48
  • `a` is a local, automatic variable. It is destroyed for you when you return from `main`. Local variables are always destroyed for you. – Alan Stokes Jul 19 '17 at 19:49
  • 2
    Yes in this case it just disappears when the scope ends, in this case when the function `main()` ends (or as soon as it's no longer useful, optimizer will decide), all objects created on it's local scope are automatically terminated, unless you dynamically allocated them using `new`. – Havenard Jul 19 '17 at 19:49
  • Only when you are allocating directly the memory like using malloc or calloc you need to call a free to release those memory, if you are only creating objects of a class those objects lives as much as their scope do. – Genaro Morales Jul 19 '17 at 19:50
  • 1
    Why do you use the nothrow version of new? –  Jul 19 '17 at 19:51
  • @sladet Yes. It _"disappears"_ at the end of the scope. – user0042 Jul 19 '17 at 19:53
  • @manni66 is said so on some tutorial on cplusplus.com – sladet Jul 19 '17 at 19:55
  • 1
    A tutorial on what? It is used why? The usual way is to simply use new. –  Jul 19 '17 at 19:58
  • @manni66 http://www.cplusplus.com/doc/tutorial/dynamic/ – sladet Jul 19 '17 at 20:00
  • And you have to use the other method? Why? –  Jul 19 '17 at 20:02

3 Answers3

1

Your code exhibit some undefined behavior (delete on something not obtained by new ....) so be really scared and read more about UB (a disease you should always avoid).

First, take the habit of compiling with (nearly) all warnings & debug info, so with GCC compile with g++ -Wall -Wextra -g and improve your code till you get no warnings. Then use the debugger (e.g. gdb) and valgrind.

Read more about C++, so take a few days to read some good C++ books and look at some C++ reference site. Read about RAII and rule of five.

When possible, use standard containers. Read about smart pointers and use them (so in most cases, avoid raw new and delete).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • I agree with what you said, but one little note: `-Wall -Wextra` does *not* enable *all* warnings. Many (and a good default set) - yes, but not *all* - gcc has plenty of additional warnings you can enable (if you want). – Jesper Juhl Jul 19 '17 at 20:07
1

You seem a bit confused about what is dynamically allocated (on the heap) and what is automatically allocated on the stack. Whilst dynamically allocated objects need to be explicitly deallocated, automatic objects get deallocated automatically (read up on RAII).

You create a as an automatic variable

k_int a(123);

It will get deallocated automatically, in this case when the end of 'main' is reached.

If a were a dynamically allocated object, it would be allocated with new and deallocated with delete. It would be your responsibility to ensure delete gets called. There are many issues related to the correct use and deallocation of dynamic memory, so much so is that the C++ Core Guidelines advises against manual deallocation (I very strongly recommend that you read the Guidelines, they have been set up by Bjarne Stroustrup (inventor of C++) and Herb Sutter (current chair of the C++ standardization committee)).

Getting back to your problem. You try to deallocate a as though it were dynamically allocated, even though it is automatic and doesn't need explicit dellocation. As already mentioned, this is UB. One likely outcome is that the heap gets corrupted and your application terminates abnormally.

The fix is simple, just remove the delete statement.

Paul Floyd
  • 5,530
  • 5
  • 29
  • 43
1

The reason I wanna delete variables is that I don't wanna have them running for the rest of the program, that it won't exist after i close my program does not help.

Then just limit the scope of your variable so "you wont have it running for the rest of the program":

int main() {

   {
       k_int a(123);
       a.print();// I did not show the source code for this
       // a would be destroyed here
   }

   cout << "Test after delete" << endl;// Does not run, nothing does :(
}

It is actually a good practice to limit your variable lifetime to be as short as possible. Just do it right way.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • Good answer, it seems that you can take data out of this temporaral thingy, which is a good thing. http://cpp.sh/4ont7 <-- link to some code – sladet Jul 19 '17 at 20:43