axel
axel

Reputation: 444

Objective C Pointers

I am experiencing a very odd problem with pointers. As you could see from the below code, I am using a method that generates a random 4 by 4 character grid. It return a pointer to a two dimensional character array. The problem is that when i try to assign the returned pointer to another pointer and try to print the generated grid, I get just one strange symbol.

Header File

#import <Foundation/Foundation.h>

@interface GridGenerator : NSObject
{
}
-(char (*)[4]) generateGrid;
-(int (*)[2]) bbb;
-(void) print;
@end

Implementation File

#import "GridGenerator.h"

@implementation GridGenerator
-(char (*)[4])generateGrid{
    char vowels[6] = {'A','E','I','O','U','Y'};
    char consonants[20] = {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Z'};
    char grid[4][4];
    int vowelsLength = (sizeof vowels / sizeof vowels[0]);
    int consLength = (sizeof consonants / sizeof consonants[0]);
    int gridSize = (sizeof grid / sizeof grid[0]);
    for(int i=0;i<gridSize;i++){
        int vowelsInGridRow = 0;
        int noOfVowels = (arc4random() % 2) + 1;
        for(int j=0;j<gridSize;j++){
            if(noOfVowels != vowelsInGridRow){
                int vowIndex = arc4random() % vowelsLength;
                char s = vowels[vowIndex];
                grid[i][j] = s;
                vowelsInGridRow++;
            }
            else{
                int consIndex = arc4random() % consLength;
                char s = consonants[consIndex];
                grid[i][j] = s;
            }
        }
    }


    char (*sd)[4]= grid;
    return sd;      
}
-(void)print{
    char (*grid)[4] = [self generateGrid];
    NSString *s = @"\n";
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            s = [s stringByAppendingString:[NSString stringWithFormat:@"%c",grid[i][j]]];

        }
        s = [s stringByAppendingString:@"\n"];
    }
    NSLog(@"%@",s);
}

Main File(Test)

#import <Foundation/Foundation.h>
#import "Crossword.h"
#import "GridGenerator.h"
int main(int argc, const char * argv[])
{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    GridGenerator *gen = [[GridGenerator alloc] init];

    [gen print];
    [pool release];
    return 0;
}

When I run the code, you can see the result below. After the 'U' there is an inverted question mark(could not be pasted here).

2013-06-02 11:24:29.923 CrosswordTest[646:303] 
U

Do you have an idea, what could causes this to happen? I am struggling already for several hours and I cannot find any explanation.

Upvotes: 0

Views: 127

Answers (1)

justin
justin

Reputation: 104698

You are returning a reference to a temporary. Explosion (undefined behavior) should be expected.

Workaround. Create a structure:

typedef struct {char at[4][4];} t_grid;

Then populate and return the t_grid by value:

- (t_grid)generateGrid
{
  char vowels[6] = {'A','E','I','O','U','Y'};
  char consonants[20] = {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Z'};
  t_grid grid;
  ...
  int gridSize = (sizeof grid.at / sizeof grid.at[0]);
  ...
    grid.at[i][j] = s;
  ...
  return grid;
}


- (void)print
{
  t_grid grid = [self generateGrid];
  ...

Note that you should not use this approach for large arrays or variable length arrays. 4*4 octets is small.

Upvotes: 2

Related Questions