In this topic Two variables in one shared memory , you can see how to put 2 variables into one shared memory in C.
However, I want to put multiple variables into one shared memory using MapViewOfFile function.
But there's no example or solution I've found.
Types of variables are different so I can't use std::vector nor array.
How should I set arguments of CreateFileMapping and MapViewOfFile to do this?
How can I get and set an address in FileMapping which I want to read and write a variable?
It shouldn't be needed that I have to create a FileMapping for each variables, right?
Use a struct as davetherock pointed out.
You have to specify the total size of all the members for "CreateFileMapping" and for "MapViewOfFile". Then you can cast the return void pointer of MapViewOfFile to the structure pointer type.
For example, if you have a struct like
typedef struct combinedStruct {
int intVariable;
float floatVariable;
}CombinedStruct;
You have to create a pointer of type CombinedStruct and cast the return of MapViewOfFile.
CombinedStruct * structPtr = (CombinedStruct*)(MapViewOfFile(...));
Then you can access the individual variables like structPtr->intVariable and structPtr->floatVariable
This may be better suited as comment but i do not have enough reputation to comment.
I am also looking for the answer for this same question and i did as said by #Manoj AV , with one change-
In the CopyMemory Instead of retrieving it as structPtr->intVariable and structPtr->floatVariable i used structPtrfor first variable and structPtr+1 to retrieve the second variable in the structure and so on.And it runs successfully.
The easiest way to have two variables back-to-back in the same chunk of memory is to use a Struct: typedef struct vs struct definitions.
If you'd like to use shmget, you simply must adjust the size of the memory allocated
shmid = shmget (shmkey, sizeof(var1) + sizeof(var2), 0644 | IPC_CREAT);
Then, adjust the pointers as necessary.
Related
I have read the article about Memory-Mapped Files and the example about CreateFileMapping.
My question is: Can I pass a pointer to a struct or a object between two processes using memory-mapped file?
Since there are some answers that it is possible, here is struct that I want to pass:
// First Process
struct OtherStruct{};
struct MyStruct
{
unsigned long handleObject;
unsigned long *phandleObject;
OtherStruct someData;
OtherStruct *pData;
}
MyStruct dataSend = { ... };
WriteToMappedFile(data);
// Second Process
MyStruct dataReceived = ReadFromMappedFile()
As the other answers already stated, you must either rely on the address of the memory-mapped areas to be equal, or you must move from absolute addresses in your pointers to relative addressing.
One possible implementation I stumbled across recently is the offset_ptr in the Boost library, which seems to fit your use case perfectly.
The answer depends on what you want to achieve. Passing a pointer in shared memory is easy, but the other process may not be able to use it in the way you expect.
Note that a pointer contains a virtual address of the data structure it points to. Such a virtual address is only valid within the process that holds the pointed-to data structure. If you pass the pointer to another process, the other process will have its own virtual address space, and the passed pointer loses its validity.
So the answer to your question is: Yes, you can pass the pointer, but without further actions, you won't be able to successfully use this pointer in the receiving process. Specifically, you will most probably not be able to use it for accessing the struct or object it points to.
If you want to access the struct or object within the other process, you need to do the following:
Put the object itself into shared memory.
Convert the pointer to the object into an offset relative to the beginning of the memory mapped file.
Pass this offset to the other process
In the other process, use the offset to convert back to a pointer.
boost::offset_ptr can help you with part of that.
Assuming the Pointer is to a struct that is part of the same memory mapped region, yes that can make sense. but then you will have to ensure that the memory mapped region is mapped to the same virtual address, this is not always guaranteed and is a bad way to design things.
You can pass the offset instead and deal with relative offsets everywhere fpor structures present in this memory region.
If the pointer you want to pass into the memory-mapped-file is not allocated by GlobalAlloc, and not locked by GlobalLock, it can't. However, you have already the memory allocated to pass the data. So you can re-write the memory on the memory-mapped-file.
I have 2 applications that are using a shared memory segment to pass data from a writing process to a reading process. At the top of the shared memory segment, I want to declare a single header struct to contain general segment data such as buffer count values, read/write offsets, pthread mutex/condition variables, etc. The header struct does NOT contain any pointers. Then the rest of the segment is used for the actual data being passed between the 2 processes.
Since the shared memory segment is attached to the process, I am assured that the segment is indeed valid/accessible to the process. It is easy to simply cast the base segment pointer to a pointer of the header struct type and that works very well for regular data types (like ints, etc) but does not work for the non-integral data types in the struct like pthread mutex/condition variables since they have not actually been declared and allocated.
So, how do I declare and allocate my header struct to start at the specific address of my already allocated shared memory segment?
The following does not appear to work:
SmHeader header = *((SmHeader *)m_pBaseAddress);
m_pHeader = &header;
where SmHeader is a typedef of my header struct and m_pBaseAddress is the base address of the attached shared memory segment.
thanks,
-Andres
I think it doesn't work because of the way you're creating it:
// this creates a copy of the SmHeader struct, on the stack
SmHeader header = *((SmHeader *)m_pBaseAddress);
// this sets m_pHeader to address of the local variable, not
// m_pBaseAddress
m_pHeader = &header;
Try this instead:
m_pHeader = (SmHeader *) m_pBaseAddress;
If i have this code :
#include <assert.h>
class Foo {
public:
bool is_static();
bool is_stack();
bool is_dynamic();
};
Foo a;
int main()
{
Foo b;
Foo* c = new Foo;
assert( a.is_static() && !a.is_stack() && !a.is_dynamic());
assert(!b.is_static() && b.is_stack() && !b.is_dynamic());
assert(!c->is_static() && !c->is_stack() && c->is_dynamic());
delete c;
}
Is it possible to implement is_stack, is_static, is_dynamic method to do so in order to be assertions fulfilled?
Example of use: counting size of memory which particular objects of type Foo uses on stack, but not counting static or dynamic memory
This cannot be done using standard C++ facilities, which take pains to ensure that objects work the same way no matter how they are allocated.
You can do it, however, by asking the OS about your process memory map, and figuring out what address range a given object falls into. (Be sure to use uintptr_t for arithmetic while doing this.)
Scroll down to the second answer that gives a wide array of available options depending on the Operating System:
How to determine CPU and memory consumption from inside a process?
I would also recommend reading this article on Tracking Memory Alloactions in C++:
http://www.almostinfinite.com/memtrack.html
Just be aware that it's a ton of work.
while the intention is good here, the approach is not the best.
Consider a few things:
on the stack you allocate temporary variables for your methods. You
don't always have to worry about how much stack you use because the
lifetime of the temp variables is short
related to stack what you usually care about is not corrupting it,
which can happen if your program uses pointers and accesses data
outside the intended bounds. For this type of problems a isStatic
function will not help.
for dynamic memory allocation you usually override the new/ delete
operators and keep a counter to track the amount of memory used. so
again, a isDynamic function might not do the trick.
in the case of global variables (you said static but I extended the
scope a bit) which are allocated in a separate data section (not
stack nor heap) well you don't always care about them because they
are statically allocated and the linker will tell you at link time if
you don't have enough space. Plus you can check the map file if you
really want to know address ranges.
So most of your concerns are solved at compile time and to be honest you rarely care about them. And the rest are (dynamic memory allocation) are treated differently.
But if you insist on having those methods you can tell the linker to generate a map file which will give you the address ranges for all data sections and use those for your purposes.
I have this simple struct defined at the top of my cpp file:
struct sServersArray
{
TCHAR sName[128];
};
struct sServersArray sServers[1024] = {0};
What I do is store data into the .Name field in one function, and read the data in other functions.
I know this is taking up valuable memory (off of the stack/heap, I don't know which or why), and I know it should be moved somehow - to a class perhaps?
Can someone show me how to move this struct to a class and be able to have my other functions access it? I am concerned about using too much stack/heap space and know this is the wrong way to go about doing this. Thanks!
struct sServersArray
{
std::string sName;
};
std::vector<sServersArray> sServers;
Global data is allocated in a separate section of memory, not the stack, not the "heap" (free store).
Simple solution: read server names to an std::vector<std::string> and pass that around by reference. That way, your data is allocated on the heap, there are no more globals to worry about and you get rid of the arbitrary length restrictions.
(You could also create a global vector, but please don't do that. Global data is a code smell.)
How would you locate an object in memory, lets say that you have a struct defined as:
struct POINT {
int x;
int y;
};
How would I scan the memory region of my app to find instances of this struct so that I can read them out?
Thanks R.
You can't without adding type information to the struct. In memory a struct like that is nothing else than 2 integers so you can't recognize them any better than you could recognize any other object.
You can't. Structs don't store any type information (unless they have virtual member functions), so you can't distinguish them from any other block of sizeof(POINT) bytes.
Why don't you store your points in a vector or something?
You can't. You have to know the layout to know what section of memory have to represent a variable. That's a kind of protocol and that's why we use text based languages instead raw values.
You don't - how would you distinguish two arbitrary integers from random noise?
( but given a Point p; in your source code, you can obtain its address using the address-of operator ... Point* pp = &p;).
Short answer: you can't. Any (appropriately aligned) sequence of 8 bytes could potentially represent a POINT. In fact, an array of ints will be indistinguishable from an array of POINTS. In some cases, you could take advantage of knowledge of the compiler implementation to do better. For instance, if the struct had virtual functions, you could look for the correct vtable pointer - but there could also be false positives.
If you want to keep track of objects, you need to register them in their constructor and unregister them in their destructor (and pay the performance penalty), or give them their own allocator.
There's no way to identify that struct. You need to put the struct somewhere it can be found, on the stack or on the heap.
Sometimes data structures are tagged with identifying information to assist with debugging or memory management. As a means of data organization, it is among the worst possible approaches.
You probably need to a lot of general reading on memory management.
There is no standard way of doing this. The platform may specify some APIs which allow you to access the stack and the free store. Further, even if you did, without any additional information how would you be sure that you are reading a POINT object and not a couple of ints? The compiler/linker can read this because it deals with (albeit virtual) addresses and has some more information (and control) than you do.
You can't. Something like that would probably be possible on some "tagged" architecture that also supported tagging objects of user-defined types. But on a traditional architecture it is absolutely impossible to say for sure what is stored in memory simply by looking at the raw memory content.
You can come closer to achieving what you want by introducing a unique signature into the type, like
struct POINT {
char signature[8];
int x;
int y;
};
and carefully setting it to some fixed and "unique" pattern in each object of POINT type, and then looking for that pattern in memory. If it is your application, you can be sure with good degree of certainty that each instance of the pattern is your POINT object. But in general, of course, there will never be any guarantee that the pattern you found belongs to your object, as opposed to being there purely accidentally.
What everyone else has said is true. In memory, your struct is just a few bytes, there's nothing in particular to distinguish it.
However, if you feel like a little hacking, you can look up the internals of your C library and figure out where memory is stored on the heap and how it appears. For example, this link shows how stuff gets allocated in one particular system.
Armed with this knowledge, you could scan your heap to find allocated blocks that were sizeof(POINT), which would narrow down the search considerably. If you look at the table you'll notice that the file name and line number of the malloc() call are being recorded - if you know where in your source code you're allocating POINTs, you could use this as a reference too.
However, if your struct was allocated on the stack, you're out of luck.