C ++ memory management for reference types

I'm still a pretty novice programmer, and I have a question about C ++ memory management with refence types.

First of all, my understanding of reference types:

The pointer is pushed onto the stack, and the actual data that the pointer points to is created and pushed onto the heap. The standard arrays and user-defined classes are refence types. It's right? Secondly, my main question is: do the c and C ++ memory management mechanisms (malloc, free and new, delete) always handle this correctly and free the memory pointed to by the class or array? Does everything work if these pointers are somehow reassigned to other objects of the same size / type on the heap? What if the class has a pointing element pointing to another object? I suppose that removing / releasing a class object does not release what its pointer to an element points to, right?

Thanks everyone!

-R

+6
c ++ c memory-management stack heap
source share
6 answers

It looks like you are approaching C ++ from a managed language such as C #. In C ++, everything is a little different.

What you describe as reference types does not exist in C ++. Types in C ++ are not "reference types" and are not "value types". They are just "types." Regardless of whether they are processed through references (or pointers) or by value, it completely depends on the code that uses the type (and not the type definition). In contrast, in languages ​​like C #, a type declarator decides whether the type should be treated as a reference or value. C ++ has something called a link, but it has nothing to do with what you are describing. At the end, I mentioned references to C ++.

Now let's see if we can handle several parts of your question:

The pointer is pushed onto the stack, and the actual data that the pointer points to is created and pushed onto the heap.

May be. That would be true if you create such an object, for example:

class MyClass { /* ... */ }; ... MyClass* pObj1 = new MyClass(); MyClass* pObj2 = (MyClass*)malloc( sizeof(MyClass) ); 

But if you create the object as follows:

 MyClass obj3; 

In the latter case, the object is allocated on the stack and has no pointer or reference. You are manipulating it as a "value type".

 MyClass *pObj3 = &obj3; 

Now pObj3 is a pointer (on the stack) to obj3 , which is also on the stack. See? There is no connection between the definition of a class and where the objects of this class are stored. It depends on how you use this type. This is a fairly common combination of objects for both the stack and the heap of the same type.

The standard arrays and user-defined classes are refence types. Is it correct?

Not; Arrays are just a collection of objects of the same type / size located in consecutive memory cells. An array can be allocated on the stack or on the heap, as with separate objects.

C and C ++ do not put any separate semantics in arrays (with one exception, I will specify per second). Once they are selected, this is just a bunch of objects that happen sequentially. It is up to your program to use array operations or direct pointer operations to access individual members. It means:

  • arrayOfClass[i] exactly matches the expression ((Class*)*(array + i)) . In C, you can even say i[arrayOfClass] , which means that arrayOfClass[i] (C ++ will complain because it has more stringent type rules).
  • You can use array operators in pointers for objects that are not part of the array (and probably fail)
  • You can use normal pointer operations on array elements.
  • You can allocate a “large” chunk of memory and “create your own array” by interpreting smaller consecutive fragments of this memory as if they were members of an array of smaller objects (this is exactly what you get when you use malloc ()).

Arrays are not types in themselves; it's just a convenient way to select multiple objects and a way to make pointers that are more convenient in some cases.

The only exception that comes to my mind is the rule "arrays are not special" - these are case arrays allocated in C ++ via new . When you allocate an array through new , it leaves information (usually on the heap next to the array, but this is not necessary) about how many elements are contained in the array when it was allocated. Then, to delete the array, use the special delete [] operator. delete [] finds and uses this extra bit of information to properly delete all elements of the array.

Secondly, my main question is: do the c and C ++ memory management mechanisms (malloc, free and new, delete) always handle this correctly and free the memory pointed to by the class or array?

As long as you do everything right, yes.

Does everything work if these pointers are somehow reassigned to other objects of the same size / type on the heap?

Yes for free() , although using pointers to a different type when you call free () (other than void* ) is a rather unusual task. There is legitimate use of such things, but they are advanced topics. You might want your design to be developed by an experienced developer to make sure that it really fits.

delete is another matter; if you use a pointer to a type other than what is stored in the buffer when you delete , the behavior is "undefined" (aka you will most likely crash). This is because delete does more than free() does; it also calls the object's destructor method, and the compiler relies on the type of pointer to invoke the correct method. If you use the wrong type of pointer, the wrong method will be called and who knows what will happen. You can put something else in the buffer after new , but this may require a non-trivial amount of work, and again is an advanced topic.

Also note that you should never allocate malloc() and free with delete , and also not allocate with new and free with free() . Make sure your methods are paired properly.

What if the class has a pointing element pointing to another object? I suppose that removing / releasing a class object does not release what its pointer to an element points to, right?

In C ++, the canonical way to handle this is that the class must have a destructor, and the destructor will take care of freeing the pointer element. In C, you have no choice, and you need to clear the pointer element manually before clearing the external pointer.

Everything assumes that the object owns the contents indicated by the member pointer. In managed languages ​​such as C #, all objects “belong” at runtime and are deleted under the control of the garbage collector, so you don’t have to worry about that. In C ++. who "owns" the objects specified in the member elements is determined by the semantics of your program, not the language, and you should pay attention to when it is time to delete the embedded objects. If you skip the right time to delete an object, you skip memory; if you delete it too soon, you will get undefined behavior and crashes (when some code tries to use an object that has already been deleted).

Now the C ++ link is basically a pointer with a little sugar coverage, designed to make it easier to use certain pointers. Basically, you can do almost nothing with links that you cannot do in C ++ simply by using pointers; a few exceptions are advanced topics that I will skip (I would have to consider it to give a theme of justice, and I have no resources).

For your point of view, a C ++ link is just a pointer that looks like a stack object.

 CMyClass pObj1 = new CMyClass(); CMyClass& myObject = pObj1; // Create a reference to the object pointed by pObj1 pObj1->Method1(); // Use the pointer to call Method1 pObj1.Method1(); // Use the reference to call Method1 

Given your level of knowledge in C ++, I can stay away from links for now, until you realize that memory management in C / C ++ is a bit better.

+16
source share

I assume that removing / releasing an object of a class does not release what the element pointer points to correctly?

This is true by default, so C ++ classes have destructors. For example:

 class C { int* x; public: C () : x (new int[10]) {} // constructor }; C* cptr = new C; // a pointer to a C object 

If I remove cptr , a memory leak will occur, since x will not be freed. Therefore, I will add a destructor to C :

 class C { ... ~C () {delete [] x;} // destructor }; 

(The rest of the questions you faced with a lot of problems. It seems that you are confused in Java and C ++, so most of your question does not make sense. I answered only this fragment to give you an example on how to automatically free resources. I suggest you read a book in C ++ to better understand the language.)

+3
source share

I'm not sure where to start.

We have primitive types (e.g. int).

Our old friend has c struct.

We have classes.

All this can be a storage class automatically; just sitting on the stack. All can be passed by value.

Then we have a pointer to x. ( x * ). They store the address of an element on the stack or are allocated elsewhere, as in new . Once you get the pointer, you have to make sure that you are not doing what makes it invalid. If you return from a function, pointers to automatic elements in a dynamic context become invalid. If you use delete , the pointer you delete is no longer valid and, of course, is not copies of it.

Then, finally, we have the links. x & it's just syntactic sugar. Passing a link to something just passes a pointer to it. Using the reference type avoids the need to enter * characters, and he claims that the pointer-under-table will never be empty.

+2
source share

The pointer is pushed onto the stack, and the actual data that the pointer points to is created and pushed onto the heap.

A pointer is a variable that stores the address of another variable. Yes it can . A pointer can always point to a local area (or stack) or to free storage (heap).

Example:

 class Foo{ public: // For Test1 This is in the Stack // For Test2 this is in the free store int x; // For Test1 the pointer is in the Stack // AND -> It points, to where we set it (could be stack or heap) // For Test2 the pointer-variable-location is in the Free Store // AND -> Similar int *y; } int main() { // Lies in the Local Scope Foo Test1; // Test2 Lies in the Local Scope, and contains the address of the // Object, which is now on the Free Store Foo *Test2 = new Foo(); } 

My main question is: c and C ++ memory management mechanisms (malloc, free and new, delete) always handle this correctly and free the memory that the class or array points to?

First of all, try to avoid mixing and removing. Secondly, free() receives a pointer and does not check if the pointer points to a valid memory location. This means that you can try to free unallocated memory, which can cause Seg Faults. A standard example of this is

 int main() { int * x; // Points to random free(x); // Undefined behaviour } 

Other misuse of a pointer may be:

 int main() { int * x = malloc(sizeof(int) * 10); //Allocate an array of 10 ++x; // Now points to x[1]; free(x); // Give me trouble } 

Does everything work if pointers somehow reassign other objects of the same size / type to the heap?

Yes, everything can go on, but it can lead to the edge of memory. As long as you remove the old material, this is normal.

What if the class has a pointer that points to another object? I am assuming that deleting / freeing a class of an object does not release its member; the pointer indicates whether this is correct?

free() class does not call the destructor, and you can use the destructor to avoid memory leaks. Using delete , you can set a destructor to delete this other object, otherwise it will cause a memory leak.

Your message tells me that you are confusing some things, you start talking about C ++ links, but in the end you talk about pointers and free() and delete , and usually give the impression that you are confused. I think you should find a good book.

+2
source share

Classes are not necessarily reference types. If, for example, you had the following code:

 class dog { int age; char *name; }; int main() { int x; dog barry; ... } 

Then inside main, barry and x will be next to each other on the stack. Thus, the stack will contain two integers and a pointer to char.

You are right in saying that freeing an object does not free the memory that its pointers to elements make. C ++ does not perform any automatic memory management, so you must allocate and release everything manually. In this case, it would be better to give the dog a destructor, something like

 class dog { ~dog() { delete name; } } 

~ The dog will be called up when you remove the dog or when the dog goes out of scope and is removed from the stack.

+1
source share

A link is basically a constant pointer that uses the syntax of an automatic variable. You cannot change what it points to, and you cannot use it to delete an object (directly, you can use the address operator in the link to get a pointer to the mentioned object, and then delete it).

The malloc and free functions simply allocate and free memory blocks. Usually you do not need to use them directly in C ++. The new and delete allocate and free memory, but also call the constructor and destructor of the object. In the class constructor, all automatic member constructors are called, as well as destructors. If your class has an element that is a pointer, it is not automatically allocated or freed. You must explicitly do this in the constructor and destructor, or use a smart pointer such as std :: auto_ptr.

When the delete operator is used on a pointer, the destructor for the pointer type is called, so if you force the pointer to point to the wrong type with explicit casting, then the invalid destructor is called when it is deleted.

0
source share

All Articles