What are some techniques to safely handle both 32bit and 64bit pointers without a conditional macro?

StackOverflow https://stackoverflow.com/questions/1533986

Question

I'm updating some code in a library because i've found out my original code assumed 32bit pointers. I have my own thinkings on how to fix it, but for thoroughness, I want to ask what are some techniques you would use to make this code work for both 32bit and 64bit without a macro?

char *argList = (char *)malloc(sizeof(id *) * argumentsCount);

sizeof(id *) is 4 on 32bit, 8 on 64bit. I'm using char *argList to build an array of pointers to objects, then using NSArray's getObjects method:

[myNSArray getObjects:(id *)argList];

works in 32bit, crashes in 64bit (for obvious reasons)

Was it helpful?

Solution

Though I don't have all of the context, I suspect that this isn't really a 32/64 bit problem. What you probably want is something along the lines of:

id *argList = malloc(sizeof(id) * argumentsCount);

Depending on the situation, I sometimes like to allocate blocks of memory like this with the allocation already zero'd out:

id *argList = calloc(1UL, sizeof(id) * argumentsCount);

Both of these allocate a chunk of memory capable of holding argumentsCount number of pointers to objects. You can access the individual pointers like so:

argList[0] = [[NSString alloc] initWithUTF8String:argv[0]];
argList[1] = [[NSString alloc] initWithUTF8String:argv[1]];
NSLog(@"Argument 0 is: %@", argList[0]);

When you declare argList as a pointer to char type, as you did in your example, indexing individual elements (ie, argList[0], argList[1]), will access the individual bytes of the memory allocated for argList, not the individual pointers as you're probably expecting. When you declare argList as id, as I did in the above, indexing individual elements steps through the memory allocated for argList by sizeof(id) bytes. The compiler will automatically compensate for the correct pointer size for the target architecture.

Assuming that the pointer returned by malloc() is 0x1000, here's a table of the addresses that would be calculated for 32 and 64bit mode for char * and id * declarations:

    32-bit: char *  id *     64-bit: char *  id *
argList[0]: 0x1000  0x1000           0x1000  0x1000
argList[1]: 0x1001  0x1004           0x1001  0x1008

I have no idea why this ever worked for you in 32-bit mode.

OTHER TIPS

Why are you keeping ids in a C array instead of one of the collection classes available in Foundation?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top