Anonymous
Anonymous asked in Computers & InternetProgramming & Design · 1 month ago

Why does my code keep crashing is it because of shallow copying quite confused??(C++) It crashes when I implement something1.Display()?

#include <iostream>

class Something {

private:

 int* age = nullptr;

public:

 Something(int number) {

  age = new int{};

  *age = number;

 }

 Something() {

 }

 Something(const Something& source):age(source.age)

 {

 }

 int GetAgeValue() {

  return *age;

 }

 void DisplayInformation(Something s) {

  std::cout << s.GetAgeValue() << std::endl;

 }

 ~Something() {

  delete age;

 }

};

int main()

{

 Something something1(5);

 something1.DisplayInformation(something1);

}

Update:

I Am confused either it's because when creating an object I have to pass in value through the parameters thanks to the constructor. However, this wouldn't make sense since I have also provided a constructor with no parameters. It works fine when i remove something1.DisplayInformation(something1); and I am not entirely sure why?

1 Answer

Relevance
  • 1 month ago
    Favorite Answer

    The problem arises from 2 places:

     • copy constructor

     • destructor

    An overview of what happens:

    1) something1 is created successfully (member age is allocated space on the heap where the value 5 is stored correctly)

    2) DisplayInformation is called, but before that we need a temporary variable. This temp is necessary because the signature of the method says it should copy whatever argument it's given, instead of working with it directly.

    3) We enter the copy constructor in order to initialize the temp. Here, you don't allocate any space for the member age of the temp, but instead you decide to "shallow copy" the address from something1. This is not, by itself, an issue.

    4) Now we enter the DisplayInformation proper. The fact that you call this method on the object something1 has nothing to do with what data the method is actually using. Indeed, you could make this method static and it would still work the same way, as it does not rely on any member variables of "this", but instead chooses to use the members of "s".

    DisplayInformation succeeds executing the code in its body, but now we have to return the execution back to main.

    This is where something unexpected happens: the temporary variable will call its destructor and successfully dealocate the pointer stored in age.

    5) We return to main and hit the end of the block, so the execution needs to finish. This is where the application crashes. We still have something1 as an object on the stack that we need to get rid of before finishing. So something1 calls its destructor which tries to delete age. But that same exact location was already deleted by the temporary variable. This triggers an exception since we cannot delete heap space that is no longer allocated.

    Best solution: alocate some space in copy constructor (also in default constructor) instead of just copying the pointer.

    so this:

    Something(const Something& source) :age(source.age)

    becomes this:

    Something(const Something& source) :age(new int { source.age })

    • Commenter avatarLogin to reply the answers
Still have questions? Get your answers by asking now.