-2

If malloc does not create a new object but only allocates raw memory, why am I able to access the class members via the pointer to this memory?

#include <iostream>
using namespace std;

const float PI = 3.141592654;

class Circle{
    float radius;
public:
    Circle(){
        cout << "Constructor called";
    }
    ~Circle(){
        cout << "Destructor called";
    }
    void Radius(){
        cout << "Enter radius: ";
        cin >> radius;
    }
    float Area(){
        return PI * radius * radius;
    }
    void Display(){
        cout << "The circle with radius " << radius
            << " units has area = " << this->Area() << " unit" << "\xFD\n";
    }
};

int main(){
    Circle *mCircle = (Circle *)malloc(sizeof(Circle));
    mCircle->Radius();
    mCircle->Display();
    return 0;
}

Can anyone cite a source to this: In C++ the rules state that an object isn't created until the constructor is called.

Saif Khan
  • 309
  • 1
  • 2
  • 19
  • 4
    Is there any specific reason why you are using `malloc()` instead of `new()`? And no, `malloc()` doesn't setup an instance of your class correctly. – πάντα ῥεῖ Mar 19 '15 at 18:00
  • `malloc` does not call the constructor. It is not a part of C++ – Ed Heal Mar 19 '15 at 18:03
  • Answered in the C++ FAQ: https://isocpp.org/wiki/faq/freestore-mgmt#new-malloc-diff – Adam Mar 19 '15 at 18:03
  • Not particularly. I am trying to understand the exact difference between the behaviors of malloc() and new. What were the limitations of malloc() and why is new better? – Saif Khan Mar 19 '15 at 18:04
  • @سیفخان - Malloc is for C, new is for C++ - two different languages – Ed Heal Mar 19 '15 at 18:07
  • +1 Although this is code has undefined behaviour and shouldn't be used in any application, it is fair to ask about it because (for those that don't already know) it broadens one's understanding of how C++ works under the hood. – Jim Oldfield Mar 19 '15 at 18:09
  • 2
    @EdHeal: The function `malloc` is a part of the C++ language. There are purposes for calling `malloc` besides allocation of objects; such as data buffers. – Thomas Matthews Mar 19 '15 at 18:10
  • @EdHeal `malloc` is valid C++ – 463035818_is_not_an_ai Mar 19 '15 at 18:11
  • @ThomasMatthews - I agree that you can use `malloc` in C++. But in essence it is not a part of the language. – Ed Heal Mar 19 '15 at 18:12
  • @EdHeal: I know that malloc() does not call the constructor/destructor like new does. And malloc() is part of C++, as it is defined in Standard C++ (http://en.cppreference.com/w/cpp/memory/c/malloc). What I need to know is, if a new instance of my class in not set up when I use malloc(), how come I am able to use the data members/functions of this 'not-created-instance'? – Saif Khan Mar 19 '15 at 18:24

2 Answers2

4

The compiler will translate a call to a member function into a call to a static function, with an implied this parameter pointing to the object. That means the contents of the object, valid or invalid, are not relevant to the whether the call is made.

This changes if the method is virtual, since the vtable pointer must be valid. The constructor will initialize the vtable pointer. malloc does not call the constructor, it doesn't even know what a constructor is - it's leftover baggage from C.

Note that this is not specified by the standard, but is how things are typically implemented.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Does this mean the references non-static data members are also translated to static data members? – Saif Khan Mar 19 '15 at 18:28
  • 1
    @سیفخان no, data members are kept per object. Only the methods - the code doesn't need to be duplicated for every object. – Mark Ransom Mar 19 '15 at 18:31
  • Exactly! If malloc does not instantiate a new object, what will happen when I try creating multiple objects or an array of objects of my class using malloc? If new objects were really not created, I would not be able to access the data for each object separately. But I can! – Saif Khan Mar 19 '15 at 18:38
  • @سیفخان There are two parts to creating an object - allocating memory space for it, and initializing it through the constructor. `malloc` can allocate the *storage* for an object, but it can't *initialize* the object. It's important to know the difference. – Mark Ransom Mar 19 '15 at 18:58
  • I am still not clear. Why would "initializing" be part of **creating an object**? Suppose I make a class _Box_ that has a member _length_. If there is only one constructor in the class, and I _don't_ initialize _length_ in this constructor, an object will still be "created" when I say `Box b1;` b1 has an uninitialized radius, but the object, b1, **has been created**. – Saif Khan Mar 19 '15 at 19:18
  • `class Box{ int length; public: Box() { } }; int main(){ Box b1; }` In the above code, memory for b1 has been allocated, but it has not been initialized. Yet, we say that b1 has been created. Or do we not? _I am new to programming. Excuse my inability t grasp something that must be so obvious to you._ – Saif Khan Mar 19 '15 at 19:23
  • @سیفخان in your example, the constructor for `Box` will be called, but since the constructor didn't initialize the member it remains uninitialized. In the case of `malloc` it *can't* be initialized because the constructor is never called. In C++ the rules state that an object isn't created until the constructor is called. – Mark Ransom Mar 19 '15 at 19:32
  • Can you cite the source for "In C++ the rules state that an object isn't created until the constructor is called."? – Saif Khan Mar 19 '15 at 19:48
2

You can access allocated but uninitialized memory, but you cannot make valid assumptions about the contents. The member functions exist independently of objects, they are just called with this pointing to an uninitialized location.

jhnnslschnr
  • 404
  • 2
  • 9
  • What about member data? The data for each object is created when a new object is created, right? Why then, in the above code, am I able to access radius when it has not been created? (Or has it?) – Saif Khan Mar 19 '15 at 18:07
  • @سیفخان the *storage* for the data has been created, so it can be accessed. The contents of that storage can be completely uninitialized however, so there's no knowing what you'll get back. – Mark Ransom Mar 19 '15 at 18:22