Borkware Miniblog

September 6, 2007

It’s Still Just C – arrays and pointers

Filed under: irc, programming — Mark Dalrymple @ 8:35 pm

Another fine day on IRC. An individual was stating that you couldn’t pass C arrays to Objective-C methods. That surprised me, so I wrote a little little command line program to check (the program is at lisppaste.) Of course, it turns out you can – Objective-C is still just C. And because it’s just C, you have the behavior of arrays and pointers being pretty much interchangeable.

For instance, you can pass a C array to a method:

- (void) ookie: (int *) snork {
    NSLog (@"%d %d %d", snork[0], snork[1], snork[2]);
} // ookie

Or use the [] syntax:

- (void) ookie2: (int[]) snork;

or use the explicit size syntax (which doesn’t really matter for 1-D arrays):

- (void) ookie3: (int[17]) snork;

And you can pass in pointers to pointers to pass back a resized array originally allocated by malloc:

- (void) ookie4: (int**) snork
         growTo: (int) elements {
 
    *snork = realloc(*snork, sizeof(int) * elements);
    (*snork)[0] = 55;
 
    NSLog (@"(%d) %d %d %d", sizeof(snork), (*snork)[0], (*snork)[1], (*snork)[2]);
 
} // ookie4

Passing in arrays of Objective-C types isn’t a problem either:

- (void) ookie: (NSString **) snork {
    NSLog (@"%@ %@", snork[0], snork[1]);
} // ookie

Just make sure your syntax is declaring the original array is good:

NSString *blargh[] = { @"oop", @"ack" };

(the original poster had confusion about Objective-C objects needing to be pointers, having a declaration of NSColor blargh[] = { ... }; and then stating that things aren’t possible)

It does go without saying that you should prefer NSArray, or another collection class, to naked C arrays. Sometimes you need to use the lower-level mechanisms, so the power (and pain) is there if needed.

Advertisements

3 Comments »

  1. Very helpful. I have to pass an array using a void pointer and will try this. Thanks.

    Comment by Daniel — May 16, 2008 @ 10:59 am

  2. Mark,
    this works, but it results in the following compilation warning at the calling locations:
    warning: passing argument 1 of ‘myFunc’ discards qualifiers from pointer target type

    It would be nice to know a way around that…

    Tom

    Comment by Tom — May 28, 2008 @ 12:38 am

  3. Sounds almost like you’ve got a const/non-const thing going. Can you post the code? (like your ObjC method taking C stuff, and where you’re calling it from. And also if you’re in C or C++ land)

    This stuff compiles and runs OK for me: (Let’s see if the html gets mangled by wordpress… Looks like I can use ‘code’ but not ‘pre’)


    #import <Foundation/Foundation.h>

    /* compile with
    gcc -g -Wall -framework Foundation -o justc justc.m
    */

    @interface Snorgle : NSObject
    - (void) ookie: (int *) snork;
    - (void) ookie4: (int**) snork
    growTo: (int) elements;
    - (void) ookie5: (NSString **) snork;
    @end // Snorgle

    @implementation Snorgle
    - (void) ookie: (int *) snork {
    NSLog (@"%d %d %d", snork[0], snork[1], snork[2]);
    } // ookie

    - (void) ookie4: (int**) snork
    growTo: (int) elements {

    *snork = realloc(*snork, sizeof(int) * elements);
    (*snork)[0] = 55;

    NSLog (@"(%d) %d %d %d", sizeof(snork), (*snork)[0], (*snork)[1], (*snork\
    )[2]);

    } // ookie4

    - (void) ookie5: (NSString **) snork {
    NSLog (@"%@ %@", snork[0], snork[1]);
    } // ookie5

    @end // Snorgle

    int main (void) {
    Snorgle *snorgle = [[Snorgle alloc] init];

    int blah[] = {1, 2, 3};
    [snorgle ookie: blah];

    int *fnork = malloc(sizeof(int) * 4);
    fnork[0] = 18; fnork[1] = 20; fnork[2] = 22; fnork[3] = 24;
    [snorgle ookie4: &fnork
    growTo: 37];

    NSString *blarg[] = { @"oop", @"ack" };
    [snorgle ookie5:blarg];

    return (0);
    } // main

    Comment by Mark Dalrymple — May 28, 2008 @ 8:42 am


RSS feed for comments on this post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.