Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

alignment of char array

Status
Not open for further replies.

rimono

Programmer
Nov 11, 2007
8
0
0
IL
Hi,

I'm porting code from Windows to HP-UX 11.23, using gcc (I'm begining to suspect this might not be the best choice, but I thought it would be most compatible since we've already compiled on Linux with gcc).

I have in my code something similar to the folowing:
Code:
unsigned char *ch_arr = new (unsigned char)[20];
unsigned char ptr = ch_arr + 10;
unsigned int number = 100;

*((unsigned int *)ptr - 1) = number;

The last line gives a segmentation fault.
In fact, I have found that its enough to write the following in order to crash:
Code:
unsigned char *ch_arr = new (unsigned char)[20];
unsigned int number = 100;

ch_arr[2] = number;

And the same is true for any index in the array which does not divide by 4.
I assume this is an alignment problem. If I were writing new code I could work around it, but since I am porting code this is a problem. Apparently the code uses this type of code, treating char arrays as memory buffers for different types, in many places and it would be very difficult to find them all and fix them.

Is there any compilation flag that could change the alignment for me?
Any other ideas for a global fix for this?

Thanks!

RO
 
The compilation flags don't work that well. I used to use them on Solaris. It added 3 to 5K to the code, it ran slower and I still got the same problems. It won't fix every case, especially like the one you've described.

Normally, this sort of problem arises in comms buffers. The header is not a multiple of 4 so everything gets misaligned. Even when you align it to multiples of 4, if you go on to 64 bit, you'll get crashes because it now has to be aligned in multiples of 8. The only way is to reassign to another item of the correct type. eg
Code:
unsigned char* buffer = new(unsigned char)[100];
stuct receiving_s receiving;
...  code to fill the buffer
receiving = *((receiving_s*) &buffer[10]);
// now you can do what you want with receiving
 
Thanks for the insight.
The 64bit issue is indeed important, I may need that in the future and should keep it in mind.

Structures of course would have prevented this whole problem, but I'm now looking for a quick and easy solution that will save me the need to go through all the code and find all the places that this kind of practice was used. I am gradually convinced that such a solution might not exist.

Thanks!

RO
 
I doubt there is a solution. I went through a similar exercise about 12 years ago. After 10 years' silence, one that was not often used surfaced Christmas 2 years ago when they moved from 32 to 64 bit.

You'll catch most of them in the first 2 weeks. It will last about 3 months before most of them are cleared but you can never be sure that you've got the lot.

Beware of floats and doubles.
 
The code in the 1st post was unportable from the beginning.
If you want to fill unaligned (by some sort of external specifications) structures (usually in buffers) in portable manner, use memcpy/memmove calls with sizeofs.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top