473,322 Members | 1,911 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Looking for a more elegant way to do memory offsets

Hello all.

I am currently using an implementation of sysV shared memory. The entire
shared memory is allocated is one continuous block of which I get the
pointer to the head, everything should be done as offsets from this. At the
moment I have two data structures, a head to a linked list which in it
contains the pointer to the first element in the linked list( this is
redundant as far as I can work out) and the list itself. The data
structures are as follows

struct ipc_particle
{
int zone_id;
int zone[3];
int fur_flag;
double radiusR; //radius of repulsion (contact radius)
double radiusA; //radius of attraction (influence radius)
double mass; //mass
double poissons; //poissons ratio
double youngs; //Young's modulus
double zeta; //zeta potential
double force[3]; //force
double position[3]; //position psn[0]=x, psn[1]=y, psn[2]=z
double velocity[3]; //velocity

};

struct dem_mem
{
int particles;
int processors;
int run;
int time_semaphore;
double clock;
struct ipc_particle* particle_head;
};

to calculate the dem_mem->particle_head I currently use particle_head =
dem_mem_pointer+(sizeof(struct dem_mem))

to reference the elements in the linked list I just use
particle_head[offset].zone_id for example.

I don't like how I calculate the particle_head, for a start I get a warning
about adding an int to a pointer.

Basically I know that my first element is sizeof(struct dem_mem) away from
the header pointer. Is there a better way to get this?

Thanks and I hope my rambling made sense.

Mike
Nov 14 '05 #1
5 1886
mikegw wrote:
I don't like how I calculate the particle_head, for a start I get a
warning about adding an int to a pointer.

Basically I know that my first element is sizeof(struct dem_mem)
away from the header pointer. Is there a better way to get this?

Thanks and I hope my rambling made sense.


I'm not sure I understand your problem, so please forgive me if I've
missed your point.

Could you use the offsetof() macro defined in stddef.h?

http://www.opengroup.org/onlinepubs/.../stddef.h.html

Nov 14 '05 #2
In article <news:c8**********@tomahawk.unsw.edu.au>
mikegw <mi******@hotmail.spammers.must.die.com> writes:
I am currently using an implementation of sysV shared memory.
The underlying shared-memory implementation is off-topic, but
this is an issue in a "general C" sense, in one important way:
The entire shared memory is allocated is one continuous block
of which I get the pointer to the head, everything should be done
as offsets from this.
There is a way to restate this without pulling in shared-memory
issues, and it goes like this:

"I have a large block of special, but otherwise undifferentiated,
C-bytes, and I need to write a general-purpose allocator, much
like malloc(), that works within this block."

Unfortunately, the Standard C answer is "you cannot write a malloc()".
The malloc() function returns memory that is "suitably aligned"
for any data type, and Standard C does not give you -- where "you"
means "anyone other than the implementor writing malloc() in the
first place" -- the tools needed to discover this alignment.

In your case, though, you have a fighting chance, because you do
not have to write a fully-general malloc(). Instead, you can
simply collect up all the types you actually use, inside these
data structures in this special block of memory, and write an
allocator that only aligns suitably for these types.

(Or you can even just sleaze out entirely and assume that sizeof(double)
is the maximum required alignment, that the block is already aligned
for use as "double", and that your two structures, since they both
contain "double", are also so aligned. :-) )
At the moment I have two data structures, a head to a linked list
which in it contains the pointer to the first element in the linked
list (this is redundant as far as I can work out) and the list
itself.
The data structures you show here are not linked-lists.
The data structures are as follows

struct ipc_particle
{
int zone_id;
int zone[3];
int fur_flag;
double radiusR; //radius of repulsion (contact radius)
double radiusA; //radius of attraction (influence radius)
double mass; //mass
double poissons; //poissons ratio
double youngs; //Young's modulus
double zeta; //zeta potential
double force[3]; //force
double position[3]; //position psn[0]=x, psn[1]=y, psn[2]=z
double velocity[3]; //velocity

};
In particular, an "ipc_particle" structure does not contain a
pointer to another "ipc_particle", so it cannot be a list. That
leaves:
struct dem_mem
{
int particles;
int processors;
int run;
int time_semaphore;
double clock;
struct ipc_particle* particle_head;
};
and here a "struct dem_mem" does not contain a pointer to another
"dem_mem", so it cannot be a list either.
to calculate the dem_mem->particle_head I currently use particle_head =
dem_mem_pointer+(sizeof(struct dem_mem))
If "dem_mem_pointer" has type "char *", this is likely to work.

If "dem_mem_pointer" has type "struct dem_mem *", this is still
likely to work, but wastes enormous amounts of space -- you just
want to add 1, not something like 32 or so. You want to "move
forward" in your block-of-bytes by 1 "struct dem_mem" object, and
pointer arithmetic works in units of the pointed-to objects.
to reference the elements in the linked list I just use
particle_head[offset].zone_id for example.
This is not a linked-list access, but rather an array access:
a "struct dem_mem"'s particle_head points to the first element
of an array (of unspecified size) of "struct ipc_particle"s,
and you move forward in memory by "offset" units of that size:

+-----------------+
| particles |
| processors |
: ... :
| particle_head --|---------\
+-----------------+ |
|
|
/-----------------------------/
|
_\|+-----------------------...
| zone_id | zone_id |
| zone | zone |
| fur_flag | fur_flag |
: : :
| velocity | velocity |
+-----------------------...

Given that "particle_head" points to the first element (subscript
0) of the array, particle_head[0] names that entire array element
-- the whole structure, with fields like "zone_id". particle_head[1]
names the entire array element "one further along" in memory,
particle_head[2] names the entire element "two further along", and
so forth.

This is the very same pointer arithmetic, stepping along by units
of the thing pointed-to, that you get if you add 1 to a "struct
dem_mem". The only difference is that the size of the target of
a "dem_mem" pointer has no defined relationship to the size of the
target of an "ipc_particle" pointer. The distance (measured in
bytes) that "+ 1" moves, changes!
I don't like how I calculate the particle_head, for a start I get a warning
about adding an int to a pointer.
Adding an int to a pointer is fine -- this is how subscripting
works in C. The problem lies elsewhere.
Basically I know that my first element is sizeof(struct dem_mem) away from
the header pointer. Is there a better way to get this?


If you have a C99 compiler, you can replace the entire technique
with a "flexible array member", where "struct dem_mem" ends with
an unspecified number of "struct ipc_particle"s:

struct ipc_particle { ... as before ... };

struct dem_mem {
... as before, but ending with ...
struct ipc_particle particles[];
};

Now the only thing you need to your malloc()-like allocator to
handle is the "struct dem_mem" itself. See the comp.lang.c FAQ
for details on C99 flexible array members, and ways to fake them
in C89. (Given that you already depend on shared-memory, depending
on things not officially valid in C89, such as faked flexible array
members, is probably not going to cause additional portabiility
problems.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #3
I am reposting as my newsserver is useless. I have changed some code so I
have edited to realise this.

Hello all.

I am currently using an implementation of sysV shared memory. The entire
shared memory is allocated is one continuous block of which I get a pointer
to the head, I can do what ever I want WITHIN the confines of this block.
At the moment I have two data structures, ipc_particle and dem_mem.

struct ipc_particle
{
int zone_id;
int zone[3];
int fur_flag;
double radiusR; //radius of repulsion (contact radius)
double radiusA; //radius of attraction (influence radius)
double mass; //mass
double poissons; //poissons ratio
double youngs; //Young's modulus
double zeta; //zeta potential
double force[3]; //force
double position[3]; //position psn[0]=x, psn[1]=y, psn[2]=z
double velocity[3]; //velocity
};

struct dem_mem
{
int particles;
int processors;
int run;
int time_semaphore;
double clock;
};

Currently I am having difficulty navigating the structure. It is trivial to
place a single dem_mem on the head of the memory, a second dem_mem would
also be easy as I would only have to derefernce it as dem_mem_array[1]
(where struct dem_mem* dem_mem_array). However I would like to have the
second and up to n elements to be of type ipc_particle. so my memory would
look like
|dem_mem|ipc_particle|ipc_particle|ipc_particle|

as said I can get a pointer to the head of my shared memory easily, the
wrinkle is calculating the offset from the head to the first ipc_particle
element.

My current attempt looks like this

struct ipc_particle* cursor;
struct dem_mem head;

blah blah blah

cursor = head+(sizeof(struct dem_mem));

Now I know this does not work.

What will?

Thanks

Mike
Nov 14 '05 #4
On Mon, 24 May 2004 11:48:55 +1000, "mikegw"
<mi******@hotmail.spammers.must.die.com> wrote:
I am reposting as my newsserver is useless. I have changed some code so I
have edited to realise this.

Hello all.

I am currently using an implementation of sysV shared memory. The entire
shared memory is allocated is one continuous block of which I get a pointer
to the head, I can do what ever I want WITHIN the confines of this block.
At the moment I have two data structures, ipc_particle and dem_mem.

struct ipc_particle
{
int zone_id;
int zone[3];
int fur_flag;
double radiusR; //radius of repulsion (contact radius)
double radiusA; //radius of attraction (influence radius)
double mass; //mass
double poissons; //poissons ratio
double youngs; //Young's modulus
double zeta; //zeta potential
double force[3]; //force
double position[3]; //position psn[0]=x, psn[1]=y, psn[2]=z
double velocity[3]; //velocity
};

struct dem_mem
{
int particles;
int processors;
int run;
int time_semaphore;
double clock;
};

Currently I am having difficulty navigating the structure. It is trivial to
place a single dem_mem on the head of the memory, a second dem_mem would
also be easy as I would only have to derefernce it as dem_mem_array[1]
(where struct dem_mem* dem_mem_array). However I would like to have the
second and up to n elements to be of type ipc_particle. so my memory would
look like
|dem_mem|ipc_particle|ipc_particle|ipc_particle |

as said I can get a pointer to the head of my shared memory easily, the
wrinkle is calculating the offset from the head to the first ipc_particle
element.

My current attempt looks like this

struct ipc_particle* cursor;
struct dem_mem head;

blah blah blah

cursor = head+(sizeof(struct dem_mem));

Now I know this does not work.

What will?


This doesn't work because, when you do pointer arithmetic, C
automatically takes the size of the object being pointed to into
account. You can make the arithmetic come out correctly with
cursor = (ipc_particle*)((char*)head + sizeof(struct dem_mem));
or the simpler
cursor = (ipc_particle*)(head+1);
which is also equivalent to
cursor = (ipc_particle*)&head[1];
but this may not solve the problem due to alignment issues.

If the sizeof(struct ipc_particle) is a suitable alignment for it and
if your system has an integer type to and from which you can convert
pointers, then you can insure that the value in cursor is properly
aligned with something like:

long pointer_integer; /* long is just a common example of a
possible integer type that meets the above criteria */
pointer_integer = (int)(head+1);
pointer_integer += sizeof(struct ipc_particle)-1;
pointer_integer /= sizeof(struct ipc_particle);
pointer_integer *= sizeof(struct ipc_particle);
cursor = (struct ipc_particle*) pointer_integer;
<<Remove the del for email>>
Nov 14 '05 #5
"mikegw" <mi******@hotmail.spammers.must.die.com> wrote in message news:<c8**********@tomahawk.unsw.edu.au>...

<snip>
I am currently using an implementation of sysV shared memory. The entire
shared memory is allocated is one continuous block of which I get a pointer
to the head, I can do what ever I want WITHIN the confines of this block.
At the moment I have two data structures, ipc_particle and dem_mem.

struct ipc_particle
{
<snip
};

struct dem_mem
{
<snip>
};

Currently I am having difficulty navigating the structure. It is trivial to
place a single dem_mem on the head of the memory, a second dem_mem would
also be easy as I would only have to derefernce it as dem_mem_array[1]
(where struct dem_mem* dem_mem_array). However I would like to have the
second and up to n elements to be of type ipc_particle. so my memory would
look like
|dem_mem|ipc_particle|ipc_particle|ipc_particle|


I may have misunderstood but how about inventing a structure that
reflects what the shared memory should look like.

struct Memory_layout
{
struct dem_mem dm;
struct ipc_paricle [3];
};

void *shm_p; /* somehow points to shared memory */
/* I assume the OS has dealt with alignment
problems */

struct Memory_layout *my_shm;

my_shm = (struct Memory_layout*)shm_p;

my_shm->ipc_particle [1].fred = joe;

<snip>
Nov 14 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: James Brown | last post by:
Hi all, Having problems designing a template-class. I'll describe my scenario first then show what I've come up with so far: Need a class to provide pointer/array-like access to an area of...
14
by: phil_gg04 | last post by:
Dear C++ Experts, Over the last couple of months I have been writing my first program using shared memory. It has been something of an "in-at-the-deep-end" experience, to say the least. At...
4
by: Someonekicked | last post by:
Is it possible to read a memory address with C++; For example, If I run this code first: ************* #include <iostream> using namespace std; void main() { int *zz = new int;
16
by: Alfonso Morra | last post by:
Hi, I am at the end of my tether now - after spending several days trying to figure how to do this. I have finally written a simple "proof of concept" program to test serializing a structure...
11
by: Sushil | last post by:
Hi Gurus I've tried to come up with a small logical example of my problem. The problem is platform specific (MIPS) which I understand should not be discussed here. So here goes my example: ...
5
by: Alfonso Morra | last post by:
Hi, I am writing a messaging library which will allow me to send a generic message structure with custom "payloads". In many cases, a message must store a non-linear data structure (i.e....
12
by: aling | last post by:
Have following code snip: struct struc { int member1; int member2; } ; printf("&((struc*)0)->member2=%p\n", &((struc*)0)->member2); In VC7.1, the output is 4, the offset of member2 in struc.
11
by: ulyses | last post by:
Let's assume I have following file: 2938929384902491233..... 923949919199191919112.... File contains INTs only. What is more they are huge. For example first row in file may contain integer...
8
by: nkrisraj | last post by:
Hi, I have a following structure: typedef struct { RateData rdr; int RateID; char RateBalance; } RateInfo;
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.