0

I'm sorry if this question was asked before. I searched the internet but couldn't find any clear answer.

Here is the issue :

Let's say I have a public class called Object that has 2 attributes. One is int attr1 and the other one is char * attr2. The constructor is (I have a header file) :

Object::Object(int param1, char * param2) 
{
  attr1=param1; 
  attr2 = new char[strlen(param2)+1]; // I understand that by doing this the values are stored in the heap
  strcpy(attr2, param2); 
}

I understand that in the destructor of the class Object I need to write delete [] attr2.

In another file, main.cpp I create a new object this way :

char * name = "Aname";
Object myObject = new Object(3, name);

From what I've understood, whenever new is used, the value is stored in the heap. Therefore a delete is necessary in order to avoid memory leaks. Here I have used the new operator to create an Object. Therefore myObject is a pointer to an Object stored in the heap. I will need to do this : delete myObject when I will no longer need it.

So this is my question : since the object that myObject points to is stored in the heap, does that mean that all it's attributes are stored in the heap (including attr1 which is simply an int) ? If so, how come I don't have to free it as well (meaning use the operator delete for it in the destructor) ?

Thank you for you help!

Note : english is not my first language, sorry for the mistakes.

CSstudZ
  • 85
  • 5
  • 1
    Unrelated: *I understand that by doing this the values are stored in the heap* It's better tio use the term Dynamic Memory rather than heap. Heap is a common implementation of Dynamic Memory, but a C++ implementation could instead use fairy dust for dynamic memory so long as the implementor could make it work. – user4581301 Dec 04 '19 at 23:38
  • 2
    Side note: [Why should C++ programmers minimize use of 'new'?](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new) – user4581301 Dec 04 '19 at 23:42

1 Answers1

1

The code you showed in your second example will not compile, because

  • myObject is not declared as a pointer

  • in C++11 and later, a non-const char* pointer cannot point to a string literal.

So you need this instead:

Object::Object(int param1, const char * param2) 
{
  attr1 = param1; 
  attr2 = new char[strlen(param2)+1];
  strcpy(attr2, param2); 
}
const char * name = "Aname";
Object * myObject = new Object(3, name); // <-- note the * !

That being said, the rest of your comments are correct. Since myObject is being created with new, its data members reside in dynamic memory (ie, the heap), and you must call delete myObject to destroy it and free its memory when you are done using it. And since you are directly allocating memory for attr2 with new[], you need to manually call delete[] attr2 to free it.

However, you are NOT directly allocating memory for attr1 with new, so you DO NOT need to manually call delete attr1. The memory for attr1 is managed by the compiler and will be released automatically when myObject is destroyed.

In short, when something is allocated explicitly by a function/operator, it must be deallocated explicitly with a corresponding function/operator, eg:

  • when something is explicitly allocated with the C++ new or new[] operator, it must be explicitly deallocated with the delete or delete[] operator, respectively.

  • if something is explicitly allocated with the C runtime (m|c|re)alloc() funtion, it must be explicitly deallocated with the C runtime free() function.

  • if something is explicitly allocated with the Win32 API (Local|Global)Alloc() or (Local|Global)ReAlloc() function, it must be explicitly deallocated with the Win32 API (Local|Global)Free() function.

  • etc

Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
  • Yes! I forgot the * after Object. Thank you for your answer. Another question : is the address stored in the pointer myObject the address of the first attribute of the object I create? – CSstudZ Dec 04 '19 at 23:45
  • Side note: `char * name = "Aname";` is also illegal. `"Aname"` is a [String Literal](https://en.cppreference.com/w/cpp/language/string_literal), a constant array of characters, and cannot be assigned to a non-constant pointer without a non-Standard language extension that allows the assignment. This is often allowed for legacy reasons as it used to be quite common to assign string literals to `char *` in the old days. The bugs that resulted from trying to modify the constant string data through the non-`const` pointer were quite common, too. – user4581301 Dec 04 '19 at 23:49
  • Thank you for you answers and sides notes. They are very helpful to a beginner like me!! To clarify my previous comment, I meant it in comparison to a pointer to an array for instance, that I know stores the adress of the first element of that array. Does that work as well for my object? If a change the order in which I declare the attributes will it change where myObject points to? – CSstudZ Dec 04 '19 at 23:53
  • 1
    @CSstudZ yes, the memory address of an object is the same as the memory address of its 1st data member. However, that data member may not be what you are expecting. For instance, in a class with virtual methods, the object pointer points at the object's *virtual method table*, which is created implicitly by the compiler, it does not point at any data member that you explicitly declared in the class. – Remy Lebeau Dec 04 '19 at 23:55