Just want to ask a silly question. During push_back operation in vectors, why previous elements that are already in the vectors are rearranged when I am using a move constructor? Sorry I asked a outside topic question.
Can you put a code snippet maybe
https://paste.ofcode.org/?edit=gHRfmaMgbRbYasTEfaykAV
Move Constructor for: 10
Destructor freeing data for nullptr
Constructor for: 20
Move Constructor for: 20
Move Constructor for: 10
Destructor freeing data for nullptr
Destructor freeing data for nullptr
Constructor for: 30
Move Constructor for: 30
Move Constructor for: 10
Move Constructor for: 20
Destructor freeing data for nullptr
Destructor freeing data for nullptr
Destructor freeing data for nullptr
Constructor for: 40
Move Constructor for: 40
Destructor freeing data for nullptr
Constructor for: 50
Move Constructor for: 50
Move Constructor for: 10
Move Constructor for: 20
Move Constructor for: 30
Move Constructor for: 40
Destructor freeing data for nullptr
Destructor freeing data for nullptr
Destructor freeing data for nullptr
Destructor freeing data for nullptr
Destructor freeing data for nullptr
Destructor freeing data for:10
Destructor freeing data for:20
Destructor freeing data for:30
Destructor freeing data for:40
Destructor freeing data for:50
I want to know why after 30 is moved to the vector then previous elements values like 10 and 20 are moved too
also after 40 is moved to the vector then why previous elements like 10, 20, 30 are not rearranged. Am I missing something?
In every push_back()
it has to make sure that there is enough memory for the additional element. If the additional memory can be provided in place (i.e., there is enough room after the vector), only the new element needs to be copied. But, this seems to be not the case for the majority of your push_back()
calls. Probably because of the new operator in the Move
constructor, which clutters the heap. Then, the Move
objects have to be copied from the old memory of the vector to the new one.
BTW, you can reserve memory for a vector to make sure that it has enough memory for a distinct amount of elements.
Daniel Rossberg said:
In every
push_back()
it has to make sure that there is enough memory for the additional element. If the additional memory can be provided in place (i.e., there is enough room after the vector), only the new element needs to be copied. But, this seems to be not the case for the majority of yourpush_back()
calls. Probably because of the new operator in theMove
constructor, which clutters the heap. Then, theMove
objects have to be copied from the old memory of the vector to the new one.BTW, you can reserve memory for a vector to make sure that it has enough memory for a distinct amount of elements.
One more doubt that why destructor is not being called in reversed order but it called destructor from 10 not from 50?
This depends on the kind of iterator used to destruct the objects in the vector. I.e., this looks like a usual forward iterator. You can set a break point in Move::~Move() to investigate the implementation of the std::vector class. The standard template library (STL) is a library written in C++.
Thanks @Daniel Rossberg :grinning:
yeah I debugged it whenever it comes to destructor or move constructor it redirects to some other cpp files where it is implemented in some sort of library.
.cpp or .h?
sorry it's .h
it redirects to stl_vector.h
then something to new_allocator.h
With all the power and flexibility of C++ comes complexity.
Right. I'ts implemented in header files only. I.e., it's enough to write #include <vector>
. You don't need to bind to a vector library.
Daniel Rossberg said:
Right. I'ts implemented in header files only. I.e., it's enough to write
#include <vector>
. You don't need to bind to a vector library.
but still idk why vscode redirects me to some sort of .h files and I included vector header file.
What do you mean by "redirect"? You included vector
and this includes what's needed to implement std::vector, e.g. stl_vector.h, new_allocator.h, ....
There was once a vector.h header, which was nothing else than the vector without std::. The vector header was something like namespace std; #include <vector.h>
.
Daniel Rossberg said:
What do you mean by "redirect"? You included
vector
and this includes what's needed to implement std::vector, e.g. stl_vector.h, new_allocator.h, ....There was once a vector.h header, which was nothing else than the vector without std::. The vector header was something like
namespace std; #include <vector.h>
.
I created a breakpoint on move constructor and whenever debugging starts it jumps to another file like move.h
What is it for a move.h file? Where does it belong to? Is there already another Move class in the STL?
BTW, there is an implicit constructor Move::Move(void)
, which will be called to initialize the vector elements. When you break in this function, the place may look odd, because you haven't wrote code for this (but the compiler did). The break point's location is often in the declaration then.
However, I'm nor sure how it looks in Visual Studio.
Daniel Rossberg said:
However, I'm nor sure how it looks in Visual Studio.
omg the quality looks cheap after converting to gif lol
For me, the quality looks good. The only issue I saw were the many frames which prevents converting (at least with ImageMagic). But, MPlayer can handle it.
The header files you see there belong all to the STL. You can see the path below the tab (usr > include > c++ >
...) E.g., move.h contains the implementation of moving values in STL containers.
Daniel Rossberg said:
The header files you see there belong all to the STL. You can see the path below the tab (
usr > include > c++ >
...) E.g., move.h contains the implementation of moving values in STL containers.
I don't want to see those header files while debugging but I manage it.
Thanks @Daniel Rossberg :innocent:
:laughing: You want to use the vector STL container and you got it. It's part of your program now.
If you break inside one of your methods and this method was just called from a STL method, the debugger has to show it to you. It would be a bad debugger, if it wouldn't do this :grinning_face_with_smiling_eyes:
However, there is a shortcut through the STL stuff while debugging: Navigate with the Call Stack to the next function which doesn't belong to the STL.
Daniel Rossberg said:
:laughing: You want to use the vector STL container and you got it. It's part of your program now.
If you break inside one of your methods and this method was just called from a STL method, the debugger has to show it to you. It would be a bad debugger, if it wouldn't do this :grinning_face_with_smiling_eyes:However, there is a shortcut through the STL stuff while debugging: Navigate with the Call Stack to the next function which doesn't belong to the STL.
:neutral: :grimacing: Now I understand why it is switching to other files while debugging.
Daniel Rossberg said:
In every
push_back()
it has to make sure that there is enough memory for the additional element. If the additional memory can be provided in place (i.e., there is enough room after the vector), only the new element needs to be copied. But, this seems to be not the case for the majority of yourpush_back()
calls. Probably because of the new operator in theMove
constructor, which clutters the heap. Then, theMove
objects have to be copied from the old memory of the vector to the new one.BTW, you can reserve memory for a vector to make sure that it has enough memory for a distinct amount of elements.
Came to know about .reserve()
so it will not expand untill it hits the given range. Now move constructor and assignment will not be copied from old memory of the vector to new one everytime it is being called.
Here's a great talk that just posted from CPPCON 2022 about design patterns. Excellent speaker.. https://www.youtube.com/watch?v=PEcy1vYHb8A
Most of the CPPCON talks are available as of today: https://www.youtube.com/@CppCon
Last updated: Jan 09 2025 at 00:46 UTC