1

The problem is that since you can use std:bind in a loop with an arbitrary number of iterations, the storage cannot be inline. It doesn't appear to be on the heap, since it doesn't appear to generate memory leaks. It seems, then, that it must be on the stack - SOME stack. I have an application which could easily do hundreds of thousands of these binds setting up calls to a threader. Since the caller could presumably go out of scope while the threader is still working, and since the threader needs the bind until it executes the job, that information must be stored SOMEWHERE. Where is it, and how do I clean it up when the binds have served their purpose?

Example:

std::function<void()> *Jobs;  
Jobs = new std::function<void()> Jobs[nJobs];  
for (i=0; i<nJobs; ++i)  
{  
    Jobs[i] = std::bind (funtion, args, ...);  
}  
ThreadPool->QueueJobs (Jobs, nJobs); // store POINTERS to jobs  
ThreadPool->WaitForCompletion();  
delete Jobs;  

Does this look like it will work?

5
  • where do you store the objects returned by std::bind? Oct 26, 2015 at 6:27
  • Winston: That's the point. If the std:bin is an argument to a function, where does it get stored? In the past, I have done threading by calling void functions with single arguments. Those arguments were pointers to structs, and I managed the memory associated with those structs myself. But while that concept holds across multiple platforms, the code required to do it does not. C++11 offers a cross-platform way of doing it, but I can't understand how it works. It looks to me like the stuff of which stack-heap collisions are made.
    – Bruce
    Oct 26, 2015 at 15:12
  • Does this look like it will work? - try it. See if it does. If it does, ask on Code Review.SE to review it (they will want the full application - not prototype code). If it doesn't, work out a good question and ask it on Stack Overflow.
    – user40980
    Oct 26, 2015 at 16:46
  • Since Jobs is an array, you should delete[] not delete. I think you get away with sorting pointers in QueueJobs because you WaitForCompletition before deleting it. But I would suggest having QueueJobs take a copy, to avoid the possibility of the pointers being deleted. A better solution would be to replace your array with std::vector which will manage the memory for you. Oct 26, 2015 at 16:50
  • Sorry about the delete. The idea behind "POINTERS" is that QueueJobs doesn't need to make copies, and the idea behind "WaitForCompletion" is that when the main thread returns from it, the threader has finished all the Jobs and has no further use for the std::binds, at which point Jobs can be deleted. But in any case, you've answered my question. Thank you, Winston.
    – Bruce
    Oct 26, 2015 at 16:58

1 Answer 1

5

The return value of std::bind is entirely on the stack. If you just called std::bind and did nothing else with it it would be on the stack and then disappear when it went out of scope.

In order to do anything useful with the result of std::bind you must have explicitly or implicitly made a copy of it, probably to some place in the heap.

For example, if you did this:

std::function foo(std::bind(this, "yellow"));

The std::function will copy the result of std::bind to the heap. When the std::function is destroyed it will automatically release the memory for the copy.

If you did something like:

vector_of_function.push_back(std::function(std::bind(this, "yellow")));

The std::bind will be copied into heap allocated by the std::function and the std::function will be copied into heap allocated by the std::vector. But in neither case do you need to worry about it because the vector and function will take care of deallocation when they are destroyed.

The rule in C++ is that whatever you new you must delete. Since the standard library is responsible for new the copies in these cases, the standard library will delete them.

4
  • Now that makes sense. I'll revise my original post with an example. Please comment on it.
    – Bruce
    Oct 26, 2015 at 16:36
  • 1
    Your answer is technically incorrect, as it ignores return value optimization, meaning that the value returned by bind is likely to be placed immediately in its destination, which in the example given is on the heap not the stack. However, this makes no practical difference, so your answer is correct in spirit.
    – Jules
    Oct 27, 2015 at 0:21
  • @Jules, yes, you are technically correct: the best kind of correct. I thought that discussing that would be too confusing. Oct 27, 2015 at 0:37
  • maybe you can mention type erasure
    – v.oddou
    May 14, 2019 at 6:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.