I use shared memory a LOT and for all kinds of different things. The one thing you can't do with it is save pointers because a pointer in one process' address space is not valid to another process. However, you can save and use offsets between processes. Anyway, I usually "map" a data structure to shared memory. It's as easy as just casting a pointer to the data of your structure. You could declare a structure with nearly any kind of data you want although pointers are not recommended. Here's one example:
const size_t BufferSize = 63;
typedef TextBuffer[BufferSize+1];
typedef struct
{
int InCount;
int OutCount;
TextBuffer String1;
TextBuffer String2;
float Float1;
float Float2;
double Double1;
double Double2;
} SmMemData;
ShMemData *psmd = (ShMemData *) shmat(shmid,(void*)0,0);
As Richard mentioned, you need a mechanism for controlling access to the data. In this example, one process could increment InCount every time it puts new data in and the other process increments OutCount every time it processes the data. That's just one possibility and you can adapt the data and logic to do what you need it to do.