473,325 Members | 2,608 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,325 software developers and data experts.

A question regarding the portability in "alligned memory allocation" post...

Hi,

In the alligned memory allocation post (a quite good article indeed).

Christian Bau suggests the following:
Expand|Select|Wrap|Line Numbers
  1. char* p = calloc (bytes + alignment + sizeof (void *));
  2. char* q = p + sizeof (void *) + alignment;
  3. q -= ((unsigned long) q) % alignment;
  4.  
  5. // If you want your code unreadable like the original author,
  6. // then change the last line to
  7. // q -= ((unsigned long) q) & (alignment - 1);
  8.  

My question is: Is the following statement portable (I have turned unsigned long into uintptr_t) - My concern is more about the % or & operators ?
Expand|Select|Wrap|Line Numbers
  1. q -= ((uintptr_t) q) % alignment;
  2.  
Guilleuss
Dec 3 '09 #1
4 1910
Banfa
9,065 Expert Mod 8TB
Yes it is portable, in fact it is more portable than the original since you are using the integer type that is defined as being the right size to hold a pointer, the original would fail on 64 bit systems on Windows for example because unsigned long has 32 bits and the pointer has 64 bits.
Dec 3 '09 #2
Thanks for your quick answer.

In fact, my question was more about the usage of the operators & or % in this case:

Since we convert the pointer into an integer and then apply the operator %, I wonder if we can use this way to align addresses on all systems.
Dec 3 '09 #3
Banfa
9,065 Expert Mod 8TB
Actually I just realised its non-portable but I will get onto that.

In the last line, in both cases, the arithmetic on the right hand side of the equation is all integer arithmetic so there is no problem with that, everything is operating on an integer and the result is a (relatively small) integer that is then used in pointer arithmetic to adjust the size of the pointer all seems fine.

But I said all seems fine and here is the kicker, the standard makes no requirements on the value of an integer that has got its value from casting from a pointer other than the value can be cast back to a similar pointer. Specifically the standard does not require that the value of the integer is the actual address of the memory location (although it would have to be related in some way) but if you imagine a system where the value of the integer representation of a pointer was not the actual memory address the arithmetic doesn't work.

Heres a worked example, imagine for a moment a system that has 31 bit addresses and uses the least significant bit to store a status or trap value of some kind for the memory location with the most significant 31 bits used for the actual memory address. A memory location of 0x00001003 would have a pointer value of 0x0001003x (where x is the status bit) assuming a status of 0 and an alignment of 8 and the right side of the equation becomes

0x00010030 % 8 = 0

However to get the address 0x00001003 to an 8 byte aligned address you need an offset of

0x00001003 % 8 = 3

The maths doesn't cause a problem, the pointer arithmetic isn't an issue but because the standard makes no requirement of the value of pointers the logic in calculating the required offset can break down when the pointers aren't the actual memory address.

However it does have to be said that I have never worked on a system where pointers were the actual memory address.


However another important point is that malloc guarantees to return a block of memory at a location that is aligned suitable for any object that the system may have. That means that if you are allocating memory only for use by the processor then you would never have to do you own alignment adjustment like this.

The only time I have seen something like this done (and I have seen it once) was when the memory was shared with an external hardware device and that external device was more efficient if the memory blocks where allocated at a specific alignment that was greater than the processors own alignment. In that case you are writing code for a very specific hardware platform (not just processor but external hardware too) so using a non-portable solution may be acceptable (well was) but it should be very clearly documented/commented.
Dec 3 '09 #4
Ok, just some more precisions and reformulations...

Actually I just realised its non-portable but I will get onto that.
This is what I was suspecting.

In the last line, in both cases, the arithmetic on the right hand side of the equation is all integer arithmetic so there is no problem with that, everything is operating on an integer and the result is a (relatively small) integer that is then used in pointer arithmetic to adjust the size of the pointer all seems fine.
I do agree.

But I said all seems fine and here is the kicker, the standard makes no requirements on the value of an integer that has got its value from casting from a pointer other than the value can be cast back to a similar pointer. Specifically the standard does not require that the value of the integer is the actual address of the memory location (although it would have to be related in some way) but if you imagine a system where the value of the integer representation of a pointer was not the actual memory address the arithmetic doesn't work.
I also agree and I would just add that with the standard there is no insurance that:
- We will get the same integer values when the same pointer is casted twice into uintptr_t; we only have the insurance that once casted back the pointers will compare equal (so hashing the resulting integer is platform specific).
- We will get a valid pointer if we perform any arithmetics on the resulting integer.
- Casting a pointer into an unsigned long (or unsigned long long) and into an uintptr_t will produce the same values (there maybe some platform specific computations done)

Heres a worked example, imagine for a moment a system that has 31 bit addresses and uses the least significant bit to store a status or trap value of some kind for the memory location with the most significant 31 bits used for the actual memory address. A memory location of 0x00001003 would have a pointer value of 0x0001003x (where x is the status bit) assuming a status of 0 and an alignment of 8 and the right side of the equation becomes
I think that we should have 0x0002006 + x = 0x1003 * 2 + x.

And consequently:
0x0002006 % 8 = 6

Nevertheless your demonstration is still relevant.

I have had a look to the way the memalign function is implemented in glibc2.11 and something similar to "q -= ((uintptr_t) q) % alignment;" is done.

My guess is that using this method to align the memory should work on most of the platforms but is somewhat specific (and not so portable).
Dec 4 '09 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: Mike Krasnik | last post by:
Hello all, I've been messing with checking memory leaks last time, and it looks like some of the memory was not freed due to the fact "library's default allocators keep free memory in a pool for...
5
by: Scott Brady Drummonds | last post by:
Hi, everyone, A coworker and I have been pondering a memory allocation problem that we're having with a very large process. Our joint research has led us to the conclusion that we may have to...
5
by: Jarek | last post by:
Hi all! I'm optimizing my C++ multi-threaded application (linux). My application consumes huge amout of memory from unknown reason. There are no memory leaks, or other allocation bugs,...
11
by: Shane Suebsahakarn | last post by:
Hi all, This might be one of those things for which there is no workaround. I'm using A2K2, and using it to perform a very large batch ouput. Both the front and back ends are MDB files, so no...
10
by: schears | last post by:
Why? Running on windows 2000 with all updates, 2G Memory, 117G Hard Drive space available. This was not an issue until I added some code to two of my c files. Any suggestions? Thanks
4
by: lawrence k | last post by:
I've a jpeg image that is 514k, which doesn't strike me as very large. Yet I'm running out of error when I try to resize it: Fatal error: Allowed memory size of 20971520 bytes exhausted (tried to...
1
by: Joe Peterson | last post by:
I've been doing a lot of searching on the topic of one of Python's more disturbing issues (at least to me): the fact that if a __del__ finalizer is defined and a cyclic (circular) reference is...
0
by: Steve Holden | last post by:
Hank @ITGroup wrote: Well, now you've told us a little more about your application I can understand that you need to be careful with memory allocation. The best thing you can do is to ensure...
1
by: =?Utf-8?B?Y2FzdGVyYnJpZGdl?= | last post by:
HP deskjet F2180 printer, windows XP with SP3 installed. Bought printer when we were still at SP2 and it was fine printing all my works database stuff, haven't used it for a while but now I get an...
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...
1
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...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
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...

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.