0

I probably will need to do something similar to what std::vector doing:

T *mem = malloc(...); // notice this is just memory allocation.
T t;
move... t to mem
mem->doSomething();

How I can move t over allocated memory?

How can I move object from allocated memory onto new variable.

How can I delete object from allocated memory - call d-tor manually?

Must I use placement new and assignment operators?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Nick
  • 9,962
  • 4
  • 42
  • 80
  • 1
    Why exactly do you want to do that? – Nidhoegger Jul 24 '15 at 13:44
  • yea what are you actually trying to do.... – AngryDuck Jul 24 '15 at 13:46
  • refactoring something from C. It is something very similar to std::vector. Currently have pointers to Objects, but I want to "put" objects inside the "array". Suppose you need to insert in the middle, at the moment I memmove lots of pointers and insert new pointer in the "hole". – Nick Jul 24 '15 at 13:48
  • Use a copy contructor... – Nidhoegger Jul 24 '15 at 13:48
  • 5
    Are you looking for [placement new](http://stackoverflow.com/questions/222557/what-uses-are-there-for-placement-new)? – Michael Jul 24 '15 at 13:48
  • I am exploring possibilities for optimisation. Pls don't tell me to use std::vector :) – Nick Jul 24 '15 at 13:49
  • Allocate your objects using `new`, then put the pointer inside the array (if you know what you are doing and casting always correct, you can even use void pointers to store whatever object you want) – Nidhoegger Jul 24 '15 at 13:50
  • @Michael - well not sure how it will be faster. I could do a new object with placement new and copy c-tor. but is there other better way? – Nick Jul 24 '15 at 13:51
  • @Nidhoegger - this is what I already have. But I ant to remove pointers and put actual objects into the array. – Nick Jul 24 '15 at 13:52
  • @Nick: Is `T` a class of your own? If so, you could define a custom allocator for it. – Michael Jul 24 '15 at 13:56

2 Answers2

1

Like this, but if you don't know what you're doing then I would avoid doing this:

#include <new>
#include <stdlib.h>

void* mem = malloc(sizeof(T));
T t;
T* tt = new(mem) T( std::move(t) );
tt->doSomething();
tt->~T();
free(mem);

You can't literally "move" t to that memory, t will always be where it was created, but you can create another object at that location, as a copy of t (using a move constructor to make the copy if it has one, but that still leaves t where it was and still existing).

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • Still existing, but possibly empty. – nwp Jul 24 '15 at 13:53
  • Excellent, can you just include the code how to move tt over t , e.g. memory over normal variable. – Nick Jul 24 '15 at 13:57
  • @Nick, `t = tt`. if you mean something else you'll have to explain what you mean. I have no idea what "move memory over a variable" means. – Jonathan Wakely Jul 24 '15 at 13:58
  • @nwp yeah for some value of empty :) – Jonathan Wakely Jul 24 '15 at 14:00
  • @JonathanWakely - move object pointed by tt to local variable, so I do not need to call destructor manually. does T t2 = std::move(*tt) will work ? – Nick Jul 24 '15 at 14:10
  • 1
    @Nick No. You should still destroy `tt` if you don't like leaks. You can skip it if you can guarantee that the destructor is a noop after `T` has been moved from, but that is very fragile code. – nwp Jul 24 '15 at 14:16
  • Let me summarize if I understood correctly - if I `std::move`, it will probably `swap`, And I still need to call the d-tor or if I don't, there will be a leak. Is that correct? – Nick Jul 24 '15 at 14:21
  • 1
    @Nick, close enough. `std::move` does not destroy anything, it just casts an object to an rvalue reference, which (depending on what you do with it) might allow it to be the argument to a move constructor or move assignment operator. But that still doesn't destroy anything, the object still exists. – Jonathan Wakely Jul 24 '15 at 14:34
1

You can't move a live object, but you can move-construct another from it.

int main() {
    std::string str = "Hello World !";

    // Allocate some storage
    void *storage = std::malloc(sizeof str);

    std::cout << str << '\n';

    // Move-contruct the new string inside the storage
    std::string *str2 = new (storage) std::string(std::move(str));

    std::cout << str << '|' << *str2 << '\n';

    // Destruct the string and free the memory
    str2->~basic_string();
    free(storage);
}

Output:

Hello World !
|Hello World !
Quentin
  • 62,093
  • 7
  • 131
  • 191