4

Returning an array (Warning: Function returns address of local variable) ?

interface

int* decimalConversion(int iX);

implementation

int* decimalConversion(int iX){
    int iMult[10] = {0,0,0,0,0,0,0};

    ...

    return iMult;  // <-- Warning: Function returns address of local variable
}
2

2 Answers 2

12

You should allocate space for the array. You're returning the address of an array that was created on the stack (hence local variable warning) if you're using C in that function use malloc(my_arr_size) if not use Objective-C's alloc.

Example:

int *my_arr = calloc(10, sizeof(int)); // Make sure we get zeroed memory
// Fill array
return my_arr; // Should no longer give a warning

When done with it just use free(my_arr) same as release. Reason I did this in C is because I can see that you're returning an int* type and using C style declarations so if you're doing it in Objective-C let me know, and I can change my answer's example.

The reason you are getting this error is because local arrays get put on the stack, when you return that array you return an address in a stack frame. The problem is that when that method finishes execution that stack frame is no longer valid and therefore you cannot expect any data that was on that frame to be valid (although there are cases when this does work, but it is considered bad practice). By allocating that array on the heap you can return a heap address where your data is assured to exist until you call free() on the pointer to that data.

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

6 Comments

Ok then follow my answer and you should be just fine :)
Not sure why that clears the Warning? Using calloc to declare an array vs just declaring an array with "[ ]" both yield a pointer. The answer returned by the function is the same in both cases. I just get a warning with the other ???? With respect to calloc or malloc, depending on method calls, I have to use "retain" or the array gets lost. So I don't understand the difference?
When you define with [] you define it on the stack because the size is known, when you define with malloc or alloc you define it in the heap which unlike a stack frame is always valid until the heap block you asked for gets freed.
um... if memory arrays are put on the stack, you are then using push and pop. You can't index into it without popping everything off to get to that item, push and pop it on the stack somewhere else to keep it?, and then you push it back on to keep the array. Indexing memory using an array is dynamic memory done on the heap.
@jdl, ummmm no. You can use pointer arithmetic which is what the compiler does. His issue is that the stack frame is INVALID once the method finishes (not guaranteed data correctness) so the data could possibly be invalid since invalid stack frames do not get preserved
|
0

If you are doing this for an app written in Objective-C, I would suggest using NSArray. NSArray is an Objective-C class for immutable arrays, and doesn't require that you manually allocate memory. The only turnoff is that you have to encapsulate your integers in NSNumber objects. An example would be:

NSArray * getNums (int num) {
    NSArray * result = [NSArray arrayWithObjects:[NSNumber numberWithInt:num-1], [NSNumber numberWithInt:num], [NSNumber numberWithInt:num+1], nil];
    return result;
}
...
NSArray * myList = getNums(10);
NSLog(@"First: %d", [[myList objectAtIndex:0] intValue]);
NSLog(@"Second: %d", [[myList objectAtIndex:1] intValue]);
NSLog(@"Third: %d", [[myList objectAtIndex:2] intValue]);

You can alternatively do this:

NSArray * getNums (int num) {
    NSMutableArray * array = [NSMutableArray array];
    [array addObject:[NSNumber numberWithInt:num-1]];
    [array addObject:[NSNumber numberWithInt:num]];
    [array addObject:[NSNumber numberWithInt:num+1]];
    return array;
}
...
NSArray * myList = getNums(10);
for (int i = 0; i < [myList count]; i++) {
    NSLog(@"myList[%d] = %d", i, [myList objectAtIndex:i]);
}

The only difference is that NSMutableArray allows you to add/remove elements after the fact.

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.