質問

I read in a C++ book that malloc() & free() are liabrary functions, and thus are outside the control of the compiler.

However, if you have an operator to perform the combined act of dynamic storage allocation & initialization (new)and another operator to perform the combined act of clean up & releasing storage (delete), the compiler can still guarantee that constructors & destructors will be called for all objects.

So, I want to know that How does this is carried out by compiler? Any Example or demo will be appriciated.

Thanks in advance.

役に立ちましたか?

解決

malloc function returns a chunk of contiguous memory, that's all. How you type-cast and use it (for your objects) is your problem.

While the new operator returns objects allocated in memory. Although both returns a pointer, in the end you get the constructed objects and not raw memory in C++. Here the focus shifts from low-level memory handling to object handling with which comes type-safety. That's the reason new doesn't return void*.

Also, if you've noticed, in the former case, C, it is a function which does the allocation i.e. the language itself has no notion of allocating objects or memory. While in C++ new is an operator and thus the language inherently understands what it means to create objects dynamically. The compiler implements what the language mandates and is thus in a position to flag an error when it spots one.

An example would be:

int *ptr = malloc(sizeof(char) * 4);

Here the programmer assumes an integer is of size 4, while this might be true in his platform, it is not certainly true for all platforms. Also conceptually char and int are different types, but the type mismatch is ignored by the C compiler. All it does is calls the malloc function and assigns the address it returns to ptr. It's domain ends there, it's up to the programmer to use (or misuse?) the allocated memory. This isn't an error or weakness on the compiler's part since the language standard doesn't give more powers to the compiler to enforce more.

While in C++

int *ptr = new char[4];

would be flagged as an error; the right way to do it would be int *ptr = new int; where the types match. C++ is more stricter, by allowing lesser freedom in places where errors are common, there by leading to cleaner code. Type safety is arguably the biggest safety feature of the C++ language. Type casting has an ugly syntax for the same reason: they show weak points of a design. With a more stricter language, the compiler is able to enforce more restrictions on the developer (since humans are more error-prone, this works out well in most cases).

他のヒント

The compiler doesn't really directly "help" allocate and deallocate memory; your code has to explicitly do this. The C++ language provides deterministic execution of code when a thread leaves scope (destructors). That in turn is often used to free heap-allocated memory.

new and delete are key words in c++.

C++ compilers will generate hidden codes for you to deal with memory allocation/deallocation stuff.

For example,

struct Test() { }
Test *a = new Test();

The compiler might do something like this, (the following is pseudo code)

Test *a = (Test *)malloc(sizeof(Test));
if (a == nullptr) { throw std::bad_alloc; }
try
{
    a.Test(); //call constructor
}
catch (...)
{
     //constructor exception, free the memory first, then re-throw
     free(a);
     throw;
}

If it is for array, things will be more complicated,

struct Test() { }
Test *a = new Test[10];

The compiler might do something like this,

Test *a = (Test *)malloc(sizeof(Test) * 10);
if (a == nullptr) { throw std::bad_alloc; }
int i;
try
{
    for (i = 0; i < 10, i++)
        a[i].Test(); //call constructor
}
catch (...)
{
     //call destructor for all constructed objects
     for (int j = 0; j < i; j++)
         a[j].~Test();

     free(a);
     throw;
}

Similar logic works for delete.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top