Memory issues, new and free, etc. (C ++)

I have a few questions regarding memory handling in C ++.

  • What is the difference Mystruct *s = new Mystruct and Mystruct s ? What is going on in the memory?

  • Take a look at this code:

     struct MyStruct{ int i; float f; }; MyStruct *create(){ MyStruct tmp; tmp.i = 1337; tmp.j = .5f; return &tmp; } int main(){ MyStruct *s = create(); cout << s->i; return 0; } 

When is MyStruct tmp free? Why at the end of create() fails MyStruct tmp automatically?

Thanks!

+4
source share
9 answers

When you use the new keyword to retrieve a pointer, your structure is allocated on the heap, which ensures that it remains in place for the duration of your application (or until it is deleted).

If you do not, the structure will be allocated on the stack and will be destroyed upon completion of the area in which it was assigned.

My understanding of your example (please feel free to let me know if I'm wrong, anyone):

tmp will indeed be "freed up" (not the best word choice for the stack variable) at the end of the function, since it was allocated on the stack and this stack stack was lost. The returned pointer / memory address no longer makes any sense, and if the code works, you're just in luck (nothing has overwritten the old data).

+8
source

In question 1, you look at heap memory and stack memory. In short,

 Mystruct S; 

creates an S on the stack. When S goes beyond, it will be destroyed. Therefore, if S is inside the function, when the function returns, S is destroyed.

While

 MyStruct *S = new MyStruct(); 

In a heap. This is a memory block reserved for variable storage programs, and S will store a pointer to the initial memory block of the new MyStruct. He will always be on the heap until you free him; if you do not free it when your program ends, you will receive an unfair memory leak.

To question 2 - the local MyStruct is destroyed when the function exits; a MyStruct pointer pointing to its return value points to an undefined scope. It can still work because the OS has not yet recovered memory, but this is definitely the wrong behavior - or a safe thing.

+3
source

At first:

 Mystruct* s = new Mystruct; 

The new Mystryct allocates memory on the heap for this type of object. In C ++, it will also execute the default constructor of the type. The Mystruct* s declares a pointer variable indicating the address of the first byte of the newly allocated object memory.

Secondly:

 Mystruct s; 

It will do the same as the first, with two differences, which can be simplified as: the allocated memory for the object is on the stack and there is no pointer variable pointing to the memory, instead s is this object. The address of this object is &s ; therefore, the pointer pointing to the object s is assigned the value &s .

Why is MyStruct tmp not automatically freed at the end of create ()?

This is true. The tmp destructor starts after the return , so the address returned by the function will be in memory, which will soon be overwritten by something else, which at best will cause a segmentation error (or equivalent) and in the worst case will corrupt your data.

+1
source

Both of your questions relate to the duration and amount of storage.

First, when you dynamically select an object, the object and the pointer to it are valid until you release it. If it is an automatic variable (i.e., not dynamically allocated by new , malloc , etc., but not declared static ), the variable goes out of scope as soon as the scope of the object ends (usually, t23> at the same level as and the one in which the object was defined). It also has an “automatic storage duration", which means that storage for it also disappears when the object is not in scope.

For your second question, tmp has a scope ending in the end } create . It also has the same storage duration. A pointer to tmp is valid only within this storage duration. Once create() completes, the pointer to tmp becomes invalid and cannot be used.

+1
source

Mystruct * s = new Mystruct;

Dynamically allocates s on the heap. It will not be automatically released. (Also, s is a pointer, not a Mystruct itself).

Mystruct s;

Statically allocates s on the stack. He will be "released" when he goes beyond. *

Your code is invalid. When you reference tmp outside of create, you use a wild pointer to access dead memory. This leads to undefined behavior.

  • To a large extent. Using it out of scope is undefined, even if the value is still in memory.
0
source

Q1:

 Mystruct *s = new Mystryct; 

Creates a structural variable on the heap pointed to by s.

 Mystruct s; 

Here the structure is created on the stack.

Q2:

 MyStruct *create(){ MyStruct tmp; tmp.i = 1337; return &tmp; } 

wrong! You create a local structure variable on the stack that disappears when the function returns and any reference to it will be invalid. You must dynamically allocate the variable and you will have to manually release it later, basically.

0
source

Mystruct *s = new Mystryct is allocated to the heap.
You need to explicitly delete it.
While Mystruct s allocates structure on a stack.
It is automatically freed up when the stack is unpacked (the variable is beyond the scope), therefore for case 2 tmp will be freed up as soon as create () exits. So, you will return to the dangling pointer which is very dangerous .

If it's too complicated, follow this rule,
For every new operator called, delete must be called in the end.
For every new[] operator called, delete[] must be called in the end.

Use smart pointers that automatically delete allocated memory instead of regular pointers. If you return objects from a function, for example, to create, make sure that you distribute it using the new operator, and not on the stack, as in the example. Verify that the caller is deleting the pointer after it ends.

0
source
  • Mystruct *s = new Mystruct has a static variable, a pointer, which is allocated at the beginning of a function call on the stack. When this line works, it allocates a structure to the heap. In Mystruct s it allocates the structure on the stack “statically” when the function starts (the constructor, if any, will be executed in the declaration line).

  • "Why is MyStruct tmp not automatically freed at the end of create ()?" - Well, it is. But the memory still exists, so you can access it, and it may contain old values.

0
source
 struct MyStruct{ int i; }; MyStruct create(){ MyStruct tmp; tmp.i = 1337; return tmp; } int main(){ MyStruct s = create(); cout << si; return 0; } 

or

 struct MyStruct{ int i; }; MyStruct* create(){ MyStruct* tmp = new MyStruct; tmp->i = 1337; return tmp; } int main(){ MyStruct* s = create(); cout << s->i; delete s; return 0; } 

will work. Because the copy constructor will create a copy of the structure when it is assigned the value s in the first case. All new / deleted material (dynamic memory allocation) refers to the basics of C ++. You do not need to use any new ones or delete them to implement basic algorithms. Copy constructor, etc. They will always do the job and make the code more understandable.

If you want to use a new one, you should also read about auto-pointer, etc. There is no garbage collection in C ++. I think C ++ Thinking very well explains the concepts of dynamic memory (chapter 13).

0
source

Source: https://habr.com/ru/post/1300274/


All Articles