views:

99

answers:

2

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)

A: 

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

NSResponder
+2  A: 

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.

johne
thanks! very very thorough answer
pxl
strangely enough, it worked flawlessly until i tried to compile it in 64bit
pxl