简体   繁体   中英

Best way to work with an array of pointers in Objective-C?

I'm trying to mimic the following Java code:

int[][] multi; // DIMENSIONS ARE UNKNOWN AT CREATION TIME
// LATER ON...
multi = new int[10][];
multi[5] = new int[20];
multi[5][11] = 66;
// LATER ON...
multi = null; // PROPER WAY OF FREEING EVERYTHING

I've came out with the following Objective-C version:

int* *multi;
//
multi = malloc(10 * sizeof(int*));
multi[5] = (int *) malloc(20 * sizeof(int));
multi[5][11] = 66;
//
free(multi[5]);
free(multi);

So first, I'd like to hear if it's the best way to go. And mostly: I can't find a way to free memory in some "automatic" fashion, ie the following code is causing run-time exceptions on the IPhone:

for (int i = 0; i < 10; i++)
{
    if (multi[i] != NULL) free(multi[i]);
}

Free doesn't zero out the memory address in the pointer, it just invalidates it. So, if you're running this loop more than once, you will get exceptions when you try to free memory that has already been invalidated. You can use an NSPointerArray or wrap your integers in objects and use an NSMutableArray for your purposes, but if you just want to use what you have, and you're running the loop more than once, you will have to do something like:

int **multi;
multi = calloc(10, sizeof(int*));
multi[5] = calloc(20, sizeof(int));
//
multi[5][11] = 66;
//
for( int i = 0; i < 10; i++ ) {
  if( multi[i] ) {
    free(multi[i]);
    multi[i] = NULL;
  }
}
//
free(multi);

This way if the loop is run more than once, you won't fail. Also, I use calloc instead of malloc because it will set all the pointers to NULL and integers to 0. The first parameter is the size of the array you want (in your case) and the second parameter is the size of the type (so no multiplication is required).

First, the suggested solution in the question is not specific to Objective-C, this is standard C. The C translation of Java code looks correct.

Second, the suggested "automatic" free cannot work: malloc() does not initialize the allocated memory. I would use calloc() instead, or add a memset() after malloc().

Third, for an Objective-C version, I would consider an NSMutableArray object populated with NSMutableArray objects themselves populated with NSNumber objects. For your goal, I think that the C version is OK.

You can make a one-dimensional array and then use an index based off of your two values. That way will have less initialization code to deal with.

Also, if you defer initializing multi until you know the dimensions, you can just initialize it as if it were a static array, rather than a variable-sized one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM