Difference between new operator in C ++ and new operator in java

As far as I know, the new operator does the following: (please correct me if I am wrong.)

  • Allocates memory, and then returns a link to the first block of allocated memory. (Memory is allocated from the heap, obviously.)
  • Initialize the object (calling constructor.)

Also, the new[] operator works in a similar way, except that it does this for each element of the array.

Can someone tell me how both of these statements are different in C ++ and Java:

  • In terms of their life cycle.
  • What if they cannot allocate memory.
+7
source share
4 answers
  • In C ++, T * p = new T; ...

    • allocates enough memory for an object of type T ,

    • creates an object of type T in this memory, possibly by initializing it, and

    • returns a pointer to an object. (The pointer has the same meaning as the allocated memory address for standard new , but this is not necessary for the new[] array form.)

    In the event of a memory failure, an exception of type std::bad_alloc , the object is not created and memory is not allocated.

    If the constructor of the object throws an exception, no object is created (obviously), the memory is automatically freed immediately, and the exception is propagated.

    Otherwise, a dynamically allocated object was created, and the user must manually destroy the object and free up memory, usually by saying delete p; .

    The actual distribution and release function can be controlled in C ++. If nothing else, the global predefined function ::operator new() , but this can be replaced by the user; and if there is a static member function of T::operator new , this will be used instead.

  • In Java, this is pretty similar, only that the return value of new is something that can bind to a Java variable of type T (or its base, such as Object ), and you should always have an initializer (so you would say T x = new T(); ). The lifetime of an object is indefinite, but it is guaranteed at least as long as any variables are still related to the object, and there is no possibility (and no need) to destroy the object manually. Java has no explicit idea of ​​memory, and you cannot control the internment of allocation.

In addition, C ++ allows many different forms of new expressions (the so-called layout forms). They all create dynamic storage objects that must be destroyed manually, but they can be quite arbitrary. As far as I know, Java does not have such features.


The biggest difference is probably in use: in Java you use new all the time for everything, and you need to, as this is the only and only way to create class objects. In contrast, in C ++, you will almost never have a bare new in the user code. C ++ has unlimited variables, and so the variables themselves can be objects, and that is how objects are commonly used in C ++.

+8
source

In your "statement" I do not think that "returns a link to the first block of allocated memory, it is absolutely right." new returns a pointer (to the type of the selected object). This is subtly different from the link, although conceptually similar.

Answers to your questions:

  • In C ++, an object remains in memory (see note) until it is explicitly deleted with delete or delete [] (and you must use the one that matches what you allocated, so new int[1]; although this is the same amount of memory as new int; cannot be deleted with delete (and vice versa, delete [] cannot be used for new int ). In Java, memory is freed by the garbage collector on some specify in the future if "no memory references. "
  • Both throw an exception (C ++ throws std::bad_alloc , Java is something like OutOfMemoryError), but in C ++ you can use new(std::nothrow) ... , in which case new returns NULL if for not enough memory to satisfy the call

Note. According to the commentary, it is technically possible to β€œdestroy” an object without freeing its memory. This is a rather unusual case, and not what you should do if you DON'T have REALLY experience with C ++, and you have a VERY good reason for this. A typical use case for this is inside the delete operator corresponding to the new placement (where new is called with an existing memory address, just to build the object (s)). Again, posting a new one is pretty much a special use of the new, not what you can expect to see in normal C ++ code.

+2
source

The new operation seems to be correct in that it allocates and initializes memory.

After successfully completing new you, the programmer, are responsible for delete for using this memory. The best way to make sure this happens is to never use new directly on your own, instead preferring standard containers and algorithms, as well as stack-based objects. But if you need to allocate memory, the C ++ idiom should use a smart pointer such as unique_ptr from C ++ 11 or shared_ptr from boost or C ++ 11. This ensures that the memory is fixed properly.

If the distribution fails, calling new will throw an exception after clearing any part of the object that was created before the failure. You can use the new version (nothrow) to return a null pointer instead of (nothrow) exception, but this further increases the load on the client code.

+1
source

I don't know the details in Java, but here is what new and new[] do in C ++:

  • Allocate memory

    When you have the expression new T or new T(args) , the compiler determines which function to call to get memory

    • If type T has a corresponding member operator new , which is called
    • Otherwise, if the user has provided the corresponding global operator new , which is called.

      If operator new cannot allocate the requested memory, it calls a new handler function, which you can set using set_new_handler . This function can free some space so that the distribution can succeed, it can interrupt the program or it can throw an exception like std::bad_alloc or get from it. By default, the new handler just throws std::bad_alloc .

      The same thing happens for new T[n] , except that operator new[] is called to allocate memory.

  • Build the object accordingly. objects in newly allocated memory.

    For new T(args) , the corresponding constructor of the object is called. If the constructor throws an exception, the memory is freed by calling the corresponding operator delete (which can be found in the same places as operator new )

    For new T it depends if T is a POD (i.e., a built-in type or basically C struct / union) or not. If T is a POD, nothing happens, otherwise it is treated as new T() .

    For new T[n] this also depends on whether T POD . Again, PODs are not initialized. For non-PODs, the default constructor, in turn, calls in order for each of the objects. If one default constructor of the object is generated, no additional constructors are called, but already constructed objects (which do not include the one whose constructor is simply thrown) are destroyed (i.e., have a destructor) in the reverse order. Then the memory is freed using the corresponding operator delete[] .

  • Returns a pointer to the newly created object (s). Note that for new[] pointer will most likely not point to the beginning of the allocated memory, because there will probably be some information about the number of allocated objects preceding the constructed objects, which is used by delete[] to find out how many objects to destroy .

In all cases, objects live until they are destroyed using delete ptr (for objects allocated with normal new ) or delete[] ptr (for objects created using the new T[n] array). If not added to a third-party library, there is no garbage collection in C ++.

Note that you can also directly call operator new and operator delete to allocate raw memory. The same is true for operator new[] and operator delete[] . However, note that even for those low-level functions, you can not mix calls, for example. by freeing memory with operator delete , which you allocated with operator new[] .

You can also create an object in the allocated memory (regardless of how you got it) with the so-called new placement. This is done by pointing to the raw memory pointer as the new argument, for example: new(pMem) T(args) . To destroy such an explicitly constructed object, you can directly call the object's destructor, p->~T() .

Posting new jobs by calling operator new , which takes a pointer as an optional argument and simply returns it. The same mechanism can also be used to provide other information for operator new overloads that take appropriate additional arguments. However, while you can define the appropriate operator delete , they are used only to clean up when the object throws an exception at build time. There is no placement deletion syntax.

Another use of the new layout syntax already provided by C ++ is not new. This parameter accepts the additional parameter std::nothrow and differs from the usual new only in that it returns a null pointer if the distribution fails.

Also note that new not the only memory management mechanism in C ++. On the one hand, there are functions C malloc and free . Although usually operator new and operator new[] simply call malloc , this is not guaranteed. Therefore, you cannot mix these forms (for example, by calling free pointer pointing to the memory allocated by operator new ). On the other hand, STL containers process their distributions through dispensers, which are objects that control the distribution / deallocation of objects, as well as the construction / destruction of objects in containers.

And finally, there are those objects whose lifetime is controlled directly by the language, namely the static and automatic lifetime. Automatic lifetime objects are distributed by simply defining a type variable in the local area. They are automatically created when the execution skips this line and is automatically destroyed when the execution leaves the scope (including its scope remains with the exception). Static lifetime objects are defined in the global / namespace area or in the local area using the static keyword. They are created when the program starts (global scope / namespace) or when their definition string is executed (local scope), and they live until the end of the program when they are automatically destroyed in the reverse order of construction.

As a rule, automatic or static variables should be preferable to dynamic allocation (i, e, everything that you allocate using new or allocators), because the compiler takes care of proper destruction, unlike dynamic allocation, where you have to do it yourself. If you have dynamically allocated objects, it is advisable that their life be controlled by automatic / static objects (containers, smart pointers) for the same reason.

+1
source

All Articles