Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an object in memory pointed to by a void pointer

If I have a void* to some chunk of free memory and I know there is at least sizeof(T) available, is there any way to create an object of type T in that location in memory?

I was just going to create a T object on the stack and memcpy it over, but it seems like there must be a more elegant way to do it?

like image 902
wallacer Avatar asked Nov 16 '11 00:11

wallacer


People also ask

What does a void pointer point to?

The void pointer in C is a pointer that is not associated with any data types. It points to some data location in the storage. This means that it points to the address of variables. It is also called the general purpose pointer.

How do you make a void pointer in C++?

In such situations, we can use the pointer to void (void pointers) in C++. For example, // void pointer void *ptr; double d = 9.0; // valid code ptr = &d; The void pointer is a generic pointer that is used when we don't know the data type of the variable that the pointer points to.

How do you assign a void pointer?

Now, we want to assign the void pointer to integer pointer, in order to do this, we need to apply the cast operator, i.e., (int *) to the void pointer variable. This cast operator tells the compiler which type of value void pointer is holding.

What is void pointer in C++ with example?

void pointer in C / C++ A void pointer is a pointer that has no associated data type with it. A void pointer can hold address of any type and can be typecasted to any type.


2 Answers

Use placement new for it:

#include <new>

void *space;
new(space) T();

Remember to delete it before you free the memory:

((T*)space)->~T();

Do not create object on stack and memcpy it over, its not safe, what if the object has its address stored in a member or a member of a member?

like image 193
Dani Avatar answered Sep 16 '22 22:09

Dani


First, just knowing that sizeof(T) amount of memory is available is not sufficient. In addition you must know that the void pointer is aligned correctly for the type of object you want to allocate. Using misaligned pointers can cause either a performance hit or a crashing application, depending on your platform.

However if you know that free memory and alignment are right, you can use placement new to construct your object there. However be aware that you also have to explicitly destruct it in that case. For example:

#include <new>      // for placement new
#include <stdlib.h> // in this example code, the memory will be allocated with malloc
#include <string>   // we will allocate a std::string there
#include <iostream> // we will output it

int main()
{
  // get memory to allocate in
  void* memory_for_string = malloc(sizeof(string)); // malloc guarantees alignment
  if (memory_for_string == 0)
    return EXIT_FAILURE;

  // construct a std::string in that memory
  std::string* mystring = new(memory_for_string) std::string("Hello");

  // use that string
  *mystring += " world";
  std::cout << *mystring << std::endl;

  // destroy the string
  mystring->~string();

  // free the memory
  free(memory_for_string);

  return EXIT_SUCCESS;
}
like image 42
celtschk Avatar answered Sep 18 '22 22:09

celtschk