Use of : Construction of objects at predetermined location in C++ - c++

What is the use of Construction of objects at predetermined locations in C++?
The following code illustrates Construction at predetermined location-
void *address = (void *) 0xBAADCAFE ;
MyClass *ptr = new (address) MyClass (/*arguments to constructor*/) ;
This eventually creates object of MyClass, at the predetermined "address".
(Assuming storage pointed by address is fairly large enough to hold MyClass object).
I would like to know the use of creating objects at such predetermined locations in memory.

One scenario where placement new is useful is:
You can preallocate big buffer once and then use many placement new operators.
This gives you better performance(You don't need reallocations everytime) and less fragmented memory (when you need small memory chunks). Typically this is what an std::vector imlementation uses.
The downside is, You have to manually manage the allocated memory. Objects allocated by placement new require an explicit destructor invocation once they are not needed anymore.
Given that it is always advicable to profile your application for bottle necks instead of running over to placement new for pre-optimization.

There are mainly two cases:
The first is when -for example in an embedded system- you have to construct an object in a given well-known place.
The second is when you want -for some reason- to manage memory in a way other than the default.
In C++, an expression like pA = new(...) A(...) does two consecutive things:
calls the void* operator new(size_t, ...) function and subsequently
calls A::A(...).
Since calling new is the only way to call A::A(), adding parameters to new allows to specialize different way to manage memory. The most trivial is to "use memory already obtained by some other means".
This method is fine when the allocation and construction needs to be separated. The typical case is std::allocator, whose purpose is allocate uninitialized memory for a given quantity, while object contruction happens later.
This happens, for example, in std::vector, since it has to allocate a capacity normally wider than its actual size, and then contruct the object as they are push_back-ed in the space that already exist.
In fact the default std::allocator implementation, when asket to allocate n object, does a return reinterpret_cast<T*>(new char[n*sizeof(T)]), so allocating the space, but actually not constructing anything.
Admitting that std::vector stores:
T* pT; //the actual buffer
size_t sz; //the actual size
size_t cap; //the actual capacity
allocator<T> alloc;
an implemetation of push_back can be:
void vector<T>::push_back(const T& t)
{
if(sz==cap)
{
size_t ncap = cap + 1+ cap/2; //just something more than cap
T* npT = alloc.allocate(ncap);
for(size_t i=0; i<sz; ++i)
{
new(npT+i)T(pt[i]); //copy old values (may be move in C++11)
pt[i].~T(); // destroy old value, without deallocating
}
alloc.deallocate(pt,cap);
pT = npT;
cap = ncap;
// now we heve extra capacity
}
new(pT+sz)T(t); //copy the new value
++sz; //actual size grown
}
In essence, there is the need to separate the allocation (that relates to the buffer as a whole) with the construction of the elements (that has to happen in the already existent bufffer).

Usually you use predetermined locations in embedded or driver code, where some hardware is addressed via certain address ranges.
But in this case the storage at that address isnt used for accessing, or better it is not intended (or better dont have to be used for it, as you dont know that the new operator is doing with it), as later on the new operation is executed.
You use it as initialization value (with new not really changing it).
There come two purposes to my mind: First, in case you forgot later on a new, you instantly see in the debugger your magic address (i.e. in this case 0xBAAADCAFE).
Secondly you can use in case you fiddle around with the new operator and need an init value, so you can debug it (e.g. you can see changes).
Or you have modified your new operator that it makes whatever with that magic number (e.g. you can use it for debugging, or, like mentioned above, to really indeed use memory at a specific address for certain hardware), switch between different allocation methods, ...
EDIT: To answer it in this case correct, one needs to see what the new operator really does, you should check that news source code.

This particular behaviour is useful when you know the address of a class by having a long, DWORD, DWORD_PTR or otherwise sized pointer passed as an argument to a function and need to reconstruct a copy of the class for O-O use.
Alternatively, this could also be used to create a class in pre-allocated memory or a location which you have determined is static (ie: you are linking your application with some ancient ASM libraries).

Custom allocators, realtime (no lock here), and performance.

Related

I don't understand how new node has been created without pointer to node [duplicate]

I just learned about the C++ construct called "placement new". It allows you to exactly control where a pointer points to in memory. It looks like this:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)];
void* place = memory;
Fred* f = new(place) Fred(); // Create a pointer to a Fred(),
// stored at "place"
// The pointers f and place will be equal
...
}
(example from C++ FAQ Lite)
In this example, the this pointer of Fred will be equal to place.
I've seen it used in our team's code once or twice. In your experience, what does this construct enable? Do other pointer languages have similar constructs? To me, it seems reminiscent of equivalence in FORTRAN, which allows disparate variables to occupy the same location in memory.
It allows you to do your own memory management. Usually this will get you at best marginally improved performance, but sometimes it's a big win. For example, if your program is using a large number of standard-sized objects, you might well want to make a pool with one large memory allocation.
This sort of thing was also done in C, but since there are no constructors in C it didn't require any language support.
It is also used for embedded programming, where IO devices are often mapped to specific memory addresses
Its usefull when building your own container like objects.
For example if you were to create a vector. If you reserve space for a large number of objects you want to allocate the memory with some method that does not invoke the constructor of the object (like new char[sizeof(object) * reserveSize]). Then when people start adding objects into the vector you use placement new to copy them into allocated memory.
template<typename T>
class SillyVectorExample
{
public:
SillyVectorExample()
:reserved(10)
,size(0)
,data(new char[sizeof(T) * reserved])
{}
void push_back(T const& object)
{
if (size >= reserved)
{
// Do Somthing.
}
// Place a copy of the object into the data store.
new (data+(sizeof(T)*size)) T(object);
++size;
}
// Add other methods to make sure data is copied and dealllocated correctly.
private:
size_t reserved;
size_t size;
char* data;
};
PS. I am not advocating doing this. This is just a simplified example of how containers can work.
I've used it when constructing objects in a shared memory segment.
Placement new can be used to create type-safe unions, such as Boost's variant.
The union class contains a buffer as big as the biggest type it's specified to contain (and with sufficient alignment). It placement news objects into the buffer as required.
I use this construct when doing C++ in kernel mode.
I use the kernel mode memory allocator and construct the object on the allocated chunk.
All of this is wrapped in classes and functions, but in the end I do a placement new.
Placement new is NOT about making pointers equal (you can just use assignment for that!).
Placement new is for constructing an object at a particular location. There are three ways of constructing an object in C++, and placement new is the only one that gives you explicit control over where that object "lives". This is useful for several things, including shared memory, low-level device I/O, and memory pool/allocator implementation.
With stack allocation, the object is constructed at the top of the stack, wherever that happens to be currently.
With "regular" new, the object is constructed at an effectively arbitrary address on the heap, as managed by the standard library (unless you've overridden operator new).
Placement new says "build me an object at this address specifically", and its implementation is simply an overload of operator new that returns the pointer passed to it, as a means of getting to the remainder of the machinery of the new operator, which constructs an object in the memory returned by the operator new function.
It's also worth noting that the operator new function can be overloaded with arbitrary arguments (just as any other function). These other arguments are passed via the "new(arg 2, arg3, ..., argN)" syntax. Arg1 is always implicitly passed as "sizeof(whatever you're constructing)".
By controlling the exact placement, you can align things in memory and this can sometimes be used to improve CPU fetch/cache performance.
Never actually saw it in use, though
It can be useful when paging out memory to a file on the hard drive, which one might do when manipulating large objects.
Placement new allows the developer to allocate the memory from preallocated memory chunk. If the system is larger, then developers go for using placement new. Now I am working on a larger avionics software there we allocate the large memory that is required for the execution of application at the start. And we use the placement new to allocate the memory wherever required. It increases the performance to some amount.
seems to me like a way of allocating an object on the stack ..
I've used it to create objects based on memory containing messages received from the network.

Intentionally leak the memory of a std::vector

I need to find a way to intentionally leak (take ownership of) the internal pointer of a std::vector so that its lifetime surpasses the one of the original container and so that it can be later deleted manually.
Why? I'm working on a networked application using the C ENet library that needs to send large amounts of packets in a short amount of time.
I create network messages by writing the data to a std::vector<unsigned char>.
Then in order to create a "packet," I use the enet_packet_create function, which takes a pointer to a byte array to be sent and its size. In normal mode of operation, the function simply dynamically duplicates the given array on the heap, but there is also a "no allocate" option which only takes the pointer and size, leaving deleting to the creator using a callback function, and that's exactly what I'm trying to achieve -- the data is already there in the vector ready to be used, so there is no need to copy it again, as it could be costly.
This approach is not possible, even if vector<T> provided an interface to let you abscond with its memory. Let's get into why.
Your problem exists because the site where you're going to free the memory is not given arbitrary data. It is only given a pointer to the memory to be freed. If this were not the case, then you'd just pass a pointer to the vector<T> itself to this location, or otherwise smuggle in a vector<T> object itself.
In order to abscond with a vector<T>'s memory and successfully free it, you would have to play by vector<T>'s rules. Which means:
You have to respect the size/capacity distinction. Not all of the memory allocated for a vector<T> actually contains live Ts. So you have to know how many live Ts there are in that memory, so that you can call their destructors properly (we'll get to an issue with that later).
Now sure, for the very specific case of unsigned char, calling destructors is irrelevant, since they're trivial. But vector<T>'s interface needs to be uniform; if you can abscond with a vector<unsigned char>'s memory, then you must be able to abscond with any vector<T> in the same way. So any absconding interface must provide not just a pointer to the data, but also the size and capacity so that you can properly destroy the members of the container.
You have to respect the Allocator. Remember: the template is vector<T, Allocator>, where Allocator is the type that does the memory allocation/deallocation, as well as creating/destroying the actual Ts in the vector. And since you're allowed to provide specific objects of a particular Allocator instance, any absconding interface must store that specific Allocator object (or copy/move thereof) so that the allocation can be freed.
Again, the specific case of vector<unsigned char> doesn't care, because the default allocator std::allocator just uses ::operator new/delete to allocate/deallocate memory, and direct placement-new/destructor calls to create/destroy the Ts. But again, a general absconding interface must work with any T and any Allocator. So it must account for all of that.
Which means that, at the end of the day, when you abscond with a vector's memory, that interface must provide an object that stores a pointer to the allocation, the number of live elements in that allocation, the size of that allocation (since the Allocator interface requires that), and the Allocator instance (or copy/move thereof) to use to destroy/deallocate the object.
In short, absconding with a vector<T, Allocator>'s memory means creating a vector<T, Allocator>.
Which you can't do, as stated above. You have arrived at an inherently contradictory situation.
There are two solutions:
Change your code so that you can smuggle in a vector<T> to the location that . This could be done via some global/class-scoped/etc map from pointer-to-data to a vector<unsigned char>*. Or some other mechanism. You'll have to figure it out, because it depends on specific aspects of the system that you have not presented (this is the definition of the XY Problem).
Stop using vector<unsigned char>. Instead, just heap-allocate an array of unsigned char, which you can destroy just fine.
You don't need to leak anything. Just use the userData field of the ENetPacket structure to store the to-be-deleted std::vector, and just delete it in the callback:
void myCallback(ENetPacket *pkt) {
std::vector<uint8_t> *data=(std::vector<uint8_t> *)pkt->userData;
delete data;
}
void sendData() {
//Create the vector in heap, so it is not destroyed after returning from this function, effectively extending its life until the callback is called.
std::vector<uint8_t> *data=new std::vector<uint8_t>;
//Fill data here
ENetPacket *pkt=enet_packet_create(data.data(), data.size(), ENET_PACKET_FLAG_NO_ALLOCATE);
pkt->userData=(void*)data;
pkt->freeCallback=myCallback;
}
The userData void pointer is a usual strategy to hold opaque user data and use it in callbacks, so the user of the library can retrieve the context in which the callback has been called.
It can be anything (void*), from a state holder structure in order to do complex logic after the callback, or just a data pointer which needs to be freed like your case.
From your comments, you say that you don't want to dynamically allocate the vector.
Just remember that any data inside the vector has been dynamically allocated (unless a custom allocator has been used) and the ENetPacket structure has also been dynamically allocated (the passed flag just indicates not to allocate the data, not the structure)
Finally, if you know (or can precompute) the size of the data, a different approach would be to create the packet passing a NULL data pointer.
The function enet_packet_create will create the data buffer, and you can just fill the data directly in the packet buffer, without needing a different buffer and then copying it to the packet.
I need to find a way to intentionally leak the internal pointer of a std::vector
Only way to leak the internal buffer of std::vector is to leak the vector itself. Example:
std::vector<T>* ptr = new std::vector<T>;
ptr = nullptr; // memory leaked succesfully
But leaking memory is not a good idea in general.
I did not literally mean to create a memory leak, the memory needs to be freed.
In this case, the only solution is to make sure that the lifetime of the std::vector is longer than the usage of the buffer. A vector always releases the buffer it owns on destruction, and there is no way to extract ownership from it except into another vector.
One way to achieve that is this:
// stored somewhere with guaranteed longer lifetime than any packet
std::unordered_map<unsigned char*, std::vector<unsigned char>> storage;
void foo()
{
std::vector<unsigned char> vec;
// fill vec here
unsigned char* ptr = vec.data();
storage[ptr] = std::move(vec);
auto destroy_callback = [](unsigned char* ptr) {
storage.erase(ptr);
}
// pass ptr and destroy_callback into some async API
}
You could use a pool allocator to avoid redundant allocations for each packet.
Example adapted form this answer (now that this question has shifted from leaking to transferring ownership, this is close to a duplicate). There's also an alternative suggestion in another answer to that same question which uses a custom allocator that "steals" the ownership
The following is not an answer! It's yet another attempt to convince you to rethink your approach but it's too long for a comment. (Having said that, I must say that I love this type of hacks when it's just for fun but I hate them even more strongly when they go to production code.)
From the OP, the motivation to use the "no alloc" option is to avoid memory allocation and copying bytes inside enet_packet_create. This brings me the question why using a vector?
If you create a vector but do not fix its its capacity (with reserve or resize) from the beginning and, instead, let it to increase as you add elements, then each time capacity is increased vector will allocate memory and copy bytes which is exactly what you want to avoid.
Perhaps you know from the beginning what the final size of the vector will be. In this case, you can avoid all copies and memory allocations (but one) by reserving that size from the beginning. In this case why not simply using a new[] and delete[] as Quentin has suggested? You wouldn't have to steal memory since it would be yours. Even better, you can create an unique_ptr<unsigned char[]> (consider make_unique<unsigned char[]>), use its release method just before calling enet_packet_create to "steal" the memory and later call delete[] to free the memory.

Can I overload 'operator new' with a different return type?

Here's my situation: I want to overload "operator new" so that instead of allocating my object in a random space in memory, it gets allocated in a pre-defined memory buffer. I want to be able to save this buffer to a file and load it in the future, so I want to use handles instead of pointers. What I want, ideally, is for "operator new" to return a handle that I can use to go straight to the object's place in it's buffer. Is it possible to do this in C++(11)? If not, what are my best alternatives?
Afaik you cannot change the return type of the new operator. For your scenario you could try the following approach:
Define a Handle (or Handle<T>, if you need handles for more than one type) class, which internally stores the index into your allocation area (i.e. Handle has one single member variable index). The Handle class will need to internally somehow have access to your allocation subsystem, i.e. it will need to know where the actual storage area (buffer) is located.
Define a constructor for Handle taking a pointer (returned by your new implementation) as argument and computing the index from that (e.g. by subtracting the beginning of your storage area)
Also define a dereferencing operator (operator *) for the Handle class returning a reference to the "handled" object (e.g. by adding the index to the beginning of the storage area...)
In your code, alsways use Handle<T> instead of pointers to T, at least at every point where you actually store the Handle/pointer.
That way, when you serialize/deserialize your storage area, only indices will be written to the disk. Using the Handle class will be the same as using pointers. The computation of the actual pointers will be done internally.
Of course this will have some performance penalty, since instead of directly using pointers there will always be some computation. Also this might affect the optimization that can be done by the compiler. One idea to minimize this performance issue would be to implement a conversion operator from Handle<T> to T*, so for code pieces that use a single Handle/Pointer a lot you could easily "precompute" the pointer and use it throughout the code.
I know something that might help you.. Try this..
Standard C++ also supports a second version of new, called placement new, which constructs an object on a preallocated storage. In order for this to work we must provide the address where we want the object to be allocated as a pointer parameter:
(my_class = new (place) Myclass);
So why would you want to use placement new? Placement new is useful for constructing objects in a pre-allocated block of memory. This bypasses the work of operator new by allowing the person constructing the object to choose the memory that it is initialized into. You might do this if you have a pool of memory you want to use for constructing some objects of a class, but don't want to overload operator new for the whole class.

Getting dynamically allocated array size

In "The C++ Programming Language" book Stroustrup says:
"To deallocate space allocated by new, delete and delete[] must be able to determine the size of the object allocated. This implies that an object allocated using the standard implementation of new will occupy slightly more space than a static object. Typically, one word is used to hold the object’s size.
That means every object allocated by new has its size located somewhere in the heap. Is the location known and if it is how can I access it?
In actual fact, the typical implementation of the memory allocators store some other information too.
There is no standard way to access this information, in fact there is nothing in the standard saying WHAT information is stored either (the size in bytes, number of elements and their size, a pointer to the last element, etc).
Edit:
If you have the base-address of the object and the correct type, I suspect the size of the allocation could be relatively easily found (not necessarily "at no cost at all"). However, there are several problems:
It assumes you have the original pointer.
It assumes the memory is allocated exactly with that runtime library's allocation code.
It assumes the allocator doesn't "round" the allocation address in some way.
To illustrate how this could go wrong, let's say we do this:
size_t get_len_array(int *mem)
{
return allcoated_length(mem);
}
...
void func()
{
int *p = new int[100];
cout << get_len_array(p);
delete [] p;
}
void func2()
{
int buf[100];
cout << get_len_array(buf); // Ouch!
}
That means every object allocated by new has its size located somewhere in the heap. Is the location known and if it is how can I access it?
Not really, that is not needed for all cases. To simplify the reasoning, there are two levels at which the sizes could be needed. At the language level, the compiler needs to know what to destroy. At the allocator level, the allocator needs to know how to release the memory given only a pointer.
At the language level, only the array versions new[] and delete[] need to handle any size. When you allocate with new, you get a pointer with the type of the object, and that type has a given size.
To destroy the object the size is not needed. When you delete, either the pointer is to the correct type, or the static type of the pointer is a base and the destructor is virtual. All other cases are undefined behavior, and thus can be ignored (anything can happen). If it is the correct type, then the size is known. If it is a base with a virtual destructor, the dynamic dispatch will find the final overrider, and at that point the type is known.
There could be different strategies to manage this, the one used in the Itanium C++ ABI (used by multiple compilers in multiple platforms, although not Visual Studio) for example generates up to 3 different destructors per type, one of them being a version that takes care of releasing the memory, so although delete ptr is defined in terms of calling the appropriate destructor and then releasing the memory, in this particular ABI delete ptr call a special destructor that both destroys and releases the memory.
When you use new[] the type of the pointer is the same regardless of the number of elements in the dynamic array, so the type cannot be used to retrieve that information back. A common implementation is allocating an extra integral value and storing the size there, followed by the real objects, then returning a pointer to the first object. delete[] would then move the received pointer one integer back, read the number of elements, call the destructor for all of them and then release the memory (pointer retrieved by the allocator, not the pointer given to the program). This is really only needed if the type has a non-trivial destructor, if the type has a trivial destructor, the implementation does not need to store the size and you can avoid storing that number.
Out of the language level, the real memory allocator (think of malloc) needs to know how much memory was allocated so that the same amount can be released. In some cases that can be done by attaching the metadata to the memory buffer in the same way that new[] stores the size of the array, by acquiring a larger block, storing the metadata there and returning a pointer beyond it. The deallocator would then undo the transformation to get to the metadata.
This is, on the other hand, not always needed. A common implementation for allocators of small size is to allocate pages of memory to form pools from which the small allocations are then obtained. To make this efficient, the allocator considers only a few different sizes, and allocations that don't fit one of the sizes exactly are bumped to the next size. If you request, for example, 65 bytes, the allocator might actually give you 128 bytes (assuming pools of 64 and 128 bytes). Thus given one of the larger blocks managed by the allocator, all pointers that were allocated from it have the same size. The allocator can then find the block from which pointer was allocated and infer the size from it.
Of course, this is all implementation details that are not accessible to the C++ program in a standard portable way, and the exact implementation can differ not just based on the program, but also de execution environment. If you are interested in knowing how the information is really kept in your environment, you might be able to find the information, but I would think twice before trying to use it for anything other than learning purposes.
Your are not deleting a object directly, instead you send a pointer to delete operator.
Reference C++
You use delete by following
it with a pointer to a block of memory originally allocated with new:
int * ps = new int; // allocate memory with new
. . . // use the memory
delete ps; // free memory with delete when done
This removes the memory to which ps points; it doesn’t remove the pointer ps itself.
You can reuse ps, for example, to point to another new allocation

What are uses of the C++ construct "placement new"?

I just learned about the C++ construct called "placement new". It allows you to exactly control where a pointer points to in memory. It looks like this:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)];
void* place = memory;
Fred* f = new(place) Fred(); // Create a pointer to a Fred(),
// stored at "place"
// The pointers f and place will be equal
...
}
(example from C++ FAQ Lite)
In this example, the this pointer of Fred will be equal to place.
I've seen it used in our team's code once or twice. In your experience, what does this construct enable? Do other pointer languages have similar constructs? To me, it seems reminiscent of equivalence in FORTRAN, which allows disparate variables to occupy the same location in memory.
It allows you to do your own memory management. Usually this will get you at best marginally improved performance, but sometimes it's a big win. For example, if your program is using a large number of standard-sized objects, you might well want to make a pool with one large memory allocation.
This sort of thing was also done in C, but since there are no constructors in C it didn't require any language support.
It is also used for embedded programming, where IO devices are often mapped to specific memory addresses
Its usefull when building your own container like objects.
For example if you were to create a vector. If you reserve space for a large number of objects you want to allocate the memory with some method that does not invoke the constructor of the object (like new char[sizeof(object) * reserveSize]). Then when people start adding objects into the vector you use placement new to copy them into allocated memory.
template<typename T>
class SillyVectorExample
{
public:
SillyVectorExample()
:reserved(10)
,size(0)
,data(new char[sizeof(T) * reserved])
{}
void push_back(T const& object)
{
if (size >= reserved)
{
// Do Somthing.
}
// Place a copy of the object into the data store.
new (data+(sizeof(T)*size)) T(object);
++size;
}
// Add other methods to make sure data is copied and dealllocated correctly.
private:
size_t reserved;
size_t size;
char* data;
};
PS. I am not advocating doing this. This is just a simplified example of how containers can work.
I've used it when constructing objects in a shared memory segment.
Placement new can be used to create type-safe unions, such as Boost's variant.
The union class contains a buffer as big as the biggest type it's specified to contain (and with sufficient alignment). It placement news objects into the buffer as required.
I use this construct when doing C++ in kernel mode.
I use the kernel mode memory allocator and construct the object on the allocated chunk.
All of this is wrapped in classes and functions, but in the end I do a placement new.
Placement new is NOT about making pointers equal (you can just use assignment for that!).
Placement new is for constructing an object at a particular location. There are three ways of constructing an object in C++, and placement new is the only one that gives you explicit control over where that object "lives". This is useful for several things, including shared memory, low-level device I/O, and memory pool/allocator implementation.
With stack allocation, the object is constructed at the top of the stack, wherever that happens to be currently.
With "regular" new, the object is constructed at an effectively arbitrary address on the heap, as managed by the standard library (unless you've overridden operator new).
Placement new says "build me an object at this address specifically", and its implementation is simply an overload of operator new that returns the pointer passed to it, as a means of getting to the remainder of the machinery of the new operator, which constructs an object in the memory returned by the operator new function.
It's also worth noting that the operator new function can be overloaded with arbitrary arguments (just as any other function). These other arguments are passed via the "new(arg 2, arg3, ..., argN)" syntax. Arg1 is always implicitly passed as "sizeof(whatever you're constructing)".
By controlling the exact placement, you can align things in memory and this can sometimes be used to improve CPU fetch/cache performance.
Never actually saw it in use, though
It can be useful when paging out memory to a file on the hard drive, which one might do when manipulating large objects.
Placement new allows the developer to allocate the memory from preallocated memory chunk. If the system is larger, then developers go for using placement new. Now I am working on a larger avionics software there we allocate the large memory that is required for the execution of application at the start. And we use the placement new to allocate the memory wherever required. It increases the performance to some amount.
seems to me like a way of allocating an object on the stack ..
I've used it to create objects based on memory containing messages received from the network.