Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does std::move make sense on a stack variable

Tags:

c++

c++11

I need to create a list of struct of size 1024. So I'm trying to optimize push operation into the list by making use of move semantics. But move semantics makes sense only for heap allocated memory(as per my knowledge). Can somebody suggest me a better way of doing this. This is my code

#include <iostream>
#include <list>
    
struct St {
    int32_t arr[1024];
};
    
int main() {
    std::list<St> struct_list;
    for(int32_t i = 0; i < 1024; ++i) {
        St st; // stack allocated and memory gets deallocated after each loop
        std::cout << &st << std::endl;
        struct_list.emplace_back(std::move(st)); // I feel std::move doesn't make any sense here even if I implement move constructor, still data gets copied into the std::list which is allocated in heap, so not efficient.
        std::cout << &struct_list.back() << "\n" << std::endl;
    }
        
    return EXIT_SUCCESS;
}
like image 338
Harry Avatar asked Jan 24 '23 13:01

Harry


2 Answers

Given your current definition of St:

struct St {
    int32_t arr[1024];
};

Technically, moving and copying both results is the same for this particular definition of St.

However, semantically it does make sense to mark st for moving as you are done with it, and st will be destroyed anyway. For example, if you later decide to change the definition of St to something like:

struct St {
    std::vector<int32_t> vec;
};

Then, it will make a difference – the vector data member will be moved instead of copied.

In short, my recommendation is to focus on the semantics of the move operation – i.e., does it make sense for the object to be moved? Well, if you are going to dispose of the object anyway, then it very likely does.

like image 68
ネロク・ゴ Avatar answered Jan 27 '23 02:01

ネロク・ゴ


If you would manage to upgrade to C++17, you could use the return value of emplace_back in order to first add it to the list and then fill it. You could (if default constructable, as your example) first emplace_back a new instance, than use .back() to get it and fill it in.

Stack allocations and deallocations ain't expensive, especially for PODs. It's the logic you do onto it that's important.

Regarding the moving, for this example, the std::move will do the same as copying, so no, you don't need it. However, if this would have been an array of std::string, the std::move would allow you to move the strings from one array to the other.

like image 24
JVApen Avatar answered Jan 27 '23 04:01

JVApen