[mdlug] C Pointer Problem
A. Zimmer
andrew.zimmer at comcast.net
Fri Apr 10 13:16:44 EDT 2015
Hello,
I am attempting to convert a relatively ancient C program (ca. 1999)
into 64-bit clean code that will run on a pure 64-bit Linux system.
The program performs a certain type of digital image processing and it
will run on a 32-bit or multilib (32/64-bit) system, but it will seg fault
on pure 64-bit.
So far I've converted all integer types and corrected all GCC compiler
warnings and errors concerning 32-bit pointers. The program will now
compile without any problems but will always seg fault during run time.
Using a debugger I've traced the seg faults to some unusual pointer
casts that somehow cause trouble in 64-bit.
Here are two places where segmentation faults occur. These two functions
are defined in a header file and are used to insert in-line functions
at various places in the code:
#define peiGetFlags(image) (((imageType*)(image))->flags)
#define peiGetConvKer(image) (*(imageType**)&(image)->clientData[1])
In these functions, "imageType" is a structure and "image" is a pointer
to that structure. The gcc compiler won't complain, but when called
during run time the program seg faults.
I cannot decipher the meaning of the constructs on the right-hand side.
The first seems to cast a pointer into a pointer to imageType, which should
not really be necessary since "image" is already of that type. In fact,
I can get past the seg fault by rewriting this as "(*image).flags." But
then why would the original author use this more complicated method?
The second one has me totally baffled. I can't even guess what that
strange bit-AND is doing.
Can someone shed some light on the meaning of these strange constructs?
Here are two more examples:
#define peiGetConvInt32Factor(image) (*(int32_t*)&(image)->clientData[3])
#define peiGetConvFloat64Factor(image) (*(double*)&(image)->clientData[3])
Also, for reference, here is the structure for which these functions are
intended (most of the fields are int32_t):
struct imageType {
imageOpsType *ops;
coordType width;
coordType height;
int32_t depth; /* 1..32 */
int32_t linebytes; /* bytes per line */
int32_t allocated; /* bytes allocated */
pixelType fill; /* color to fill with */
int8_t sign;
imageType *primary; /* for secondary, assoc primary */
coordType primaryX; /* for secondary, offset in primary */
coordType primaryY; /* for secondary, offset in primary */
int8_t *data;
uint32_t flags; /* image access mode(s) */
int32_t verbose;
int32_t page; /* number of the current page */
double resX; /* pixels per unit in X */
double resY; /* pixels per unit in Y */
int32_t resUnit; /* 0=nores 1=unk 2=inch 3=cm */
char modes[PEI_MAX_MODES]; /* modes used with open */
char name[PEI_MAX_NAME];
int32_t clientData[PEI_CLIENT_SIZE]; };
I can always run this code on a multi-lib (32/64-bit) system but I'd like
to use pure 64-bit only.
More information about the mdlug
mailing list