3

I have a function that returns a variable and I want to know how to return an array the issue is it isn't an NSArray it is just an average C array like this...

-(b2Fixture*) addFixturesToBody:(b2Body*)body forShapeName:(NSString*)shape
{
    BodyDef *so = [shapeObjects objectForKey:shape];
    assert(so);
       FixtureDef *fix = so->fixtures;
    int count = -1;
    b2Fixture *Fixi[4];
    while(fix)
    {

        count++;
        NSLog(@"count = %d",count);
        Fixi[count]= body->CreateFixture(&fix->fixture);
        if (Fixi[count]!=0) {
            NSLog(@"Fixi %d is not 0",count);
        }
        if (body->CreateFixture(&fix->fixture)!=0) {
            NSLog(@"body %d is not 0",count);
        }

        fix = fix->next;

    }

    return *Fixi;

}

If you see some variable types you don't know it's because I'm using cocos2d framework to make a game but I'm returning a variable of b2Fixture... This code compiles however only saves the value of the first block of the array "fixi[0]" not the whole array like I want to pass

anyhelp :) thankyou

1
  • 3
    If you're going to return a C array (of anything), where do you intend to allocate it? (Hint: It can't be on the stack of the called function.) Commented Mar 11, 2012 at 0:45

3 Answers 3

2

You can't return a local array. You'll need to do some kind of dynamic allocation or pull a trick like having the array inside a structure.

Here is a link to an in-depth article that should help you out.

Sign up to request clarification or add additional context in comments.

3 Comments

And how would I go about doing that
malloc(3), perhaps?
A very true answer but ... should be expanded or reference one of the myriad of other answers.
2

In general returning C arrays by value is a bad idea, as arrays can be very large. Objective-C arrays are by-reference types - they are dynamically allocated and a reference, which is small, is what is passed around. You can dynamically allocate C arrays as well, using one of the malloc family for allocation and free for deallocation.

You can pass C structures around by value, and this is common, as in general structures tend to be small (or smallish anyway).

Now in your case you are using a small array, it has just 4 elements. If you consider passing these 4 values around by value is reasonable and a good fit for your design then you can do so simply by embedding the C array in a C structure:

typedef struct
{
    b2Fixture *elements[4];
} b2FixtureArray;

...

-(b2FixtureArray) addFixturesToBody:(b2Body*)body forShapeName:(NSString*)shape
{
    BodyDef *so = [shapeObjects objectForKey:shape];
    assert(so);
    FixtureDef *fix = so->fixtures;
    int count = -1;
    b2FixtureArray Fixi;
    while(fix)
    {   
        count++;
        NSLog(@"count = %d", count);
        Fixi.elements[count]= body->CreateFixture(&fix->fixture);
        if (Fixi.elements[count] != 0)
        {
            NSLog(@"Fixi %d is not 0",count);
        }
        if (body->CreateFixture(&fix->fixture) != 0)
        {
            NSLog(@"body %d is not 0", count);
        }

        fix = fix->next;    
    }    
    return Fixi;    
}

...

// sample call outline
b2FixtureArray result = [self addFixturesToBody...]

Whether this standard C "trick" for passing arrays by value is appropriate for your case you'll have to decide.

Note: If b2fixture is an Objective-C object make sure you understand the memory management implications of having a C array of objects references depending on the memory management model (MRC, ARC, GC) you are using.

3 Comments

how would I retrieve the struct that it's returning i.e. before I would write b2fixture = function now what? since its a struct and all... do I need to make a new struct of the same type
I get an error something along the lines of b2Fixture can't be saved as b2FixtureArray incompatible type
@KingPopsicle - the last line shows how it can be called. What this standard C technique does is wrap an array as the single member of a structure. So instead of array[index] you use structure.array[index] everywhere. The error you're getting sounds like you're trying to assign a b2Fixture to the structure instead of to an element of the array within the structure.
0

If you need to design function or method that has to return a fixed or limited size array, one possibility is to pass a pointer to the result array to the function or method as a parameter. Then the caller can take care of allocating space, or just use a local or instance variable array. You might want the called function to sanity check that the array parameter isn't NULL before using the array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.