why would std::equal_to cause dynamic allocation?
Clash Royale CLAN TAG#URR8PPP
up vote
6
down vote
favorite
Consider the following simple example, where I am using std::equal_to
to compare two std::pair<std::string, unsigned>
. The operator new
is overloaded so that it prints a message when allocations take place (live code here):
#include <functional>
#include <string>
#include <iostream>
// overloaded to see when heap allocations take place
void* operator new(std::size_t n)
std::cout << "Allocating " << n << std::endl;
return malloc(n);
int main()
using key_type = std::pair<std::string, unsigned>;
auto key1 = std::make_pair(std::string("a_______long______string______"), 1);
auto key2 = std::make_pair(std::string("a_______long______string______"), 1);
std::cout << "Finished initial allocationsnn" << std::endl;
std::equal_to<key_type> eq;
eq(key1, key2); // how can this cause dynamic allocation???
The message I am seeing is
Allocating 31
Allocating 31
Finished initial allocations
Allocating 31
Allocating 31
You can see there are two allocations taking place when comparing key1
and key2
. But why? std::equal_to
's operator takes its arguments by const reference so no allocation should take place... what I am missing? Thanks.
c++ heap-memory std-pair
add a comment |Â
up vote
6
down vote
favorite
Consider the following simple example, where I am using std::equal_to
to compare two std::pair<std::string, unsigned>
. The operator new
is overloaded so that it prints a message when allocations take place (live code here):
#include <functional>
#include <string>
#include <iostream>
// overloaded to see when heap allocations take place
void* operator new(std::size_t n)
std::cout << "Allocating " << n << std::endl;
return malloc(n);
int main()
using key_type = std::pair<std::string, unsigned>;
auto key1 = std::make_pair(std::string("a_______long______string______"), 1);
auto key2 = std::make_pair(std::string("a_______long______string______"), 1);
std::cout << "Finished initial allocationsnn" << std::endl;
std::equal_to<key_type> eq;
eq(key1, key2); // how can this cause dynamic allocation???
The message I am seeing is
Allocating 31
Allocating 31
Finished initial allocations
Allocating 31
Allocating 31
You can see there are two allocations taking place when comparing key1
and key2
. But why? std::equal_to
's operator takes its arguments by const reference so no allocation should take place... what I am missing? Thanks.
c++ heap-memory std-pair
Build flags/compiler command line?
â Yakk - Adam Nevraumont
35 mins ago
@Yakk-AdamNevraumont gcc 8.2.0 using c++17 with O2 optimisation
â linuxfever
32 mins ago
add a comment |Â
up vote
6
down vote
favorite
up vote
6
down vote
favorite
Consider the following simple example, where I am using std::equal_to
to compare two std::pair<std::string, unsigned>
. The operator new
is overloaded so that it prints a message when allocations take place (live code here):
#include <functional>
#include <string>
#include <iostream>
// overloaded to see when heap allocations take place
void* operator new(std::size_t n)
std::cout << "Allocating " << n << std::endl;
return malloc(n);
int main()
using key_type = std::pair<std::string, unsigned>;
auto key1 = std::make_pair(std::string("a_______long______string______"), 1);
auto key2 = std::make_pair(std::string("a_______long______string______"), 1);
std::cout << "Finished initial allocationsnn" << std::endl;
std::equal_to<key_type> eq;
eq(key1, key2); // how can this cause dynamic allocation???
The message I am seeing is
Allocating 31
Allocating 31
Finished initial allocations
Allocating 31
Allocating 31
You can see there are two allocations taking place when comparing key1
and key2
. But why? std::equal_to
's operator takes its arguments by const reference so no allocation should take place... what I am missing? Thanks.
c++ heap-memory std-pair
Consider the following simple example, where I am using std::equal_to
to compare two std::pair<std::string, unsigned>
. The operator new
is overloaded so that it prints a message when allocations take place (live code here):
#include <functional>
#include <string>
#include <iostream>
// overloaded to see when heap allocations take place
void* operator new(std::size_t n)
std::cout << "Allocating " << n << std::endl;
return malloc(n);
int main()
using key_type = std::pair<std::string, unsigned>;
auto key1 = std::make_pair(std::string("a_______long______string______"), 1);
auto key2 = std::make_pair(std::string("a_______long______string______"), 1);
std::cout << "Finished initial allocationsnn" << std::endl;
std::equal_to<key_type> eq;
eq(key1, key2); // how can this cause dynamic allocation???
The message I am seeing is
Allocating 31
Allocating 31
Finished initial allocations
Allocating 31
Allocating 31
You can see there are two allocations taking place when comparing key1
and key2
. But why? std::equal_to
's operator takes its arguments by const reference so no allocation should take place... what I am missing? Thanks.
c++ heap-memory std-pair
c++ heap-memory std-pair
edited 30 mins ago
juanchopanza
185k21294402
185k21294402
asked 42 mins ago
linuxfever
1,6481921
1,6481921
Build flags/compiler command line?
â Yakk - Adam Nevraumont
35 mins ago
@Yakk-AdamNevraumont gcc 8.2.0 using c++17 with O2 optimisation
â linuxfever
32 mins ago
add a comment |Â
Build flags/compiler command line?
â Yakk - Adam Nevraumont
35 mins ago
@Yakk-AdamNevraumont gcc 8.2.0 using c++17 with O2 optimisation
â linuxfever
32 mins ago
Build flags/compiler command line?
â Yakk - Adam Nevraumont
35 mins ago
Build flags/compiler command line?
â Yakk - Adam Nevraumont
35 mins ago
@Yakk-AdamNevraumont gcc 8.2.0 using c++17 with O2 optimisation
â linuxfever
32 mins ago
@Yakk-AdamNevraumont gcc 8.2.0 using c++17 with O2 optimisation
â linuxfever
32 mins ago
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
7
down vote
accepted
It is because you make copies of the pairs.
The types of keyX
are std::pair<std::string, int>
. eq
has has a function call operator for the arguments const std::pair<std::string, unsigned>&, const std::pair<std::string, unsigned>&
. As the types do not match, the references cannot be bound to the arguments directly. However, int
is implicitly convertible to unsigned
and so given pair is implicitly convertible to the argument pair.
So, you implicitly create a pair of temporary arguments for the comparison. The creation of the temporary strings cause the memory allocation.
If you had used std::equal_to<>
as the comparison operator, it would have not created copies as it deduces the argument types, and thus wouldn't have caused the conversion.
Arghhhh! How did I miss that? Thanks for spotting!
â linuxfever
29 mins ago
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
It is because you make copies of the pairs.
The types of keyX
are std::pair<std::string, int>
. eq
has has a function call operator for the arguments const std::pair<std::string, unsigned>&, const std::pair<std::string, unsigned>&
. As the types do not match, the references cannot be bound to the arguments directly. However, int
is implicitly convertible to unsigned
and so given pair is implicitly convertible to the argument pair.
So, you implicitly create a pair of temporary arguments for the comparison. The creation of the temporary strings cause the memory allocation.
If you had used std::equal_to<>
as the comparison operator, it would have not created copies as it deduces the argument types, and thus wouldn't have caused the conversion.
Arghhhh! How did I miss that? Thanks for spotting!
â linuxfever
29 mins ago
add a comment |Â
up vote
7
down vote
accepted
It is because you make copies of the pairs.
The types of keyX
are std::pair<std::string, int>
. eq
has has a function call operator for the arguments const std::pair<std::string, unsigned>&, const std::pair<std::string, unsigned>&
. As the types do not match, the references cannot be bound to the arguments directly. However, int
is implicitly convertible to unsigned
and so given pair is implicitly convertible to the argument pair.
So, you implicitly create a pair of temporary arguments for the comparison. The creation of the temporary strings cause the memory allocation.
If you had used std::equal_to<>
as the comparison operator, it would have not created copies as it deduces the argument types, and thus wouldn't have caused the conversion.
Arghhhh! How did I miss that? Thanks for spotting!
â linuxfever
29 mins ago
add a comment |Â
up vote
7
down vote
accepted
up vote
7
down vote
accepted
It is because you make copies of the pairs.
The types of keyX
are std::pair<std::string, int>
. eq
has has a function call operator for the arguments const std::pair<std::string, unsigned>&, const std::pair<std::string, unsigned>&
. As the types do not match, the references cannot be bound to the arguments directly. However, int
is implicitly convertible to unsigned
and so given pair is implicitly convertible to the argument pair.
So, you implicitly create a pair of temporary arguments for the comparison. The creation of the temporary strings cause the memory allocation.
If you had used std::equal_to<>
as the comparison operator, it would have not created copies as it deduces the argument types, and thus wouldn't have caused the conversion.
It is because you make copies of the pairs.
The types of keyX
are std::pair<std::string, int>
. eq
has has a function call operator for the arguments const std::pair<std::string, unsigned>&, const std::pair<std::string, unsigned>&
. As the types do not match, the references cannot be bound to the arguments directly. However, int
is implicitly convertible to unsigned
and so given pair is implicitly convertible to the argument pair.
So, you implicitly create a pair of temporary arguments for the comparison. The creation of the temporary strings cause the memory allocation.
If you had used std::equal_to<>
as the comparison operator, it would have not created copies as it deduces the argument types, and thus wouldn't have caused the conversion.
edited 24 mins ago
answered 30 mins ago
user2079303
72k550109
72k550109
Arghhhh! How did I miss that? Thanks for spotting!
â linuxfever
29 mins ago
add a comment |Â
Arghhhh! How did I miss that? Thanks for spotting!
â linuxfever
29 mins ago
Arghhhh! How did I miss that? Thanks for spotting!
â linuxfever
29 mins ago
Arghhhh! How did I miss that? Thanks for spotting!
â linuxfever
29 mins ago
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52919315%2fwhy-would-stdequal-to-cause-dynamic-allocation%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Build flags/compiler command line?
â Yakk - Adam Nevraumont
35 mins ago
@Yakk-AdamNevraumont gcc 8.2.0 using c++17 with O2 optimisation
â linuxfever
32 mins ago