user366312
user366312

Reputation: 16908

What is wrong with the following code? How to correct this?

How to return a static multidimensional array of characters?

#include<stdio.h>
#include<conio.h>

#define SIZE 3

char ** MyFunction(void)
{
    static char arr[SIZE][SIZE]={
                                    {'A', 'B', 'C'},
                                    {'D', 'E', 'F'},
                                    {'G', 'H', 'I'}
                                };
    return arr;
}

void main(void)
{
    char ** arr1 = NULL;
    int i=0;
    int j=0;

    arr1 = MyFunction();

    for(i=0 ; i<SIZE ; i++)
    {
        for(j=0 ; j<SIZE ; j++)
        {
            printf("%c, ", arr1[i][j]);
        }

        printf("\n");
    }

    getch();
}

Upvotes: 3

Views: 268

Answers (5)

user411313
user411313

Reputation: 3990

conio.h + getch() is not ANSI C. void main is not ANSI C. Take a new type, it make it easier.

#include<stdio.h>
#include<conio.h>

#define SIZE 3
typedef char CHAR3[SIZE];

CHAR3 *MyFunction(void)
{
    static CHAR3 arr[]={
                                    {'A', 'B', 'C'},
                                    {'D', 'E', 'F'},
                                    {'G', 'H', 'I'}
                                };
    return arr;
}

main(void)
{
    CHAR3 *arr1 = NULL;
    int i=0;
    int j=0;

    arr1 = MyFunction();

    for(i=0 ; i<SIZE ; i++)
    {
        for(j=0 ; j<SIZE ; j++)
        {
            printf("%c, ", arr1[i][j]);
        }

        printf("\n");
    }

   getch();
}

Upvotes: 0

Arun
Arun

Reputation: 20383

Who owns the array?

It is very important because some part of the code has to take full ownership (create, delete) of the array. Other parts of the code can read and write though.

With that philosophy, I would modify the code so that main function (in reality, it can be any function) takes ownership of arr1. main creates arr1, and passes it to other function (may be in other module) to "initialize" it. Here is a modified version of the program.

#include <stdio.h>

enum{ SIZE = 3 };

void initArray( char arr[ SIZE ][ SIZE ] ) {

    char x = 'A';

    for( int i = 0; i < SIZE; i++ ) {
        for( int j = 0; j < SIZE; j++ ) {
            arr[ i ][ j ] = x;
            x += 1;
        }
    }
}

int main()
{
    char arr1[ SIZE ][ SIZE ];
    initArray( arr1 );

    for( int i = 0; i < SIZE; i++ ) {
        for( int j = 0; j < SIZE; j++ ) {
            printf("%c, ", arr1[ i ][ j ]);
        }
        printf("\n");
    }
}

Upon spending few minutes in searching, I found a good discussion on multi-dimensional array in C.

Another comment on the side. please note that I have done couple of other changes in the code, some are design (e.g. using enum instead of #define, declaring variables (i, j in most local scope) while some are formatting. Programs are mainly for communicating with other human programmers, so readability of code is very important.

Upvotes: 0

zakirhas7
zakirhas7

Reputation: 231

change to static char ** arr[][]= ...

Upvotes: 0

John Bode
John Bode

Reputation: 123468

Given the declaration

char arr[SIZE][SIZE];

then the type of the expression arr is char (*)[SIZE]; therefore, the function type should be

char (*myFunction(void))[SIZE] // myFunction returns a pointer to a SIZE-element
{                              // array of char
  static char arr[SIZE][SIZE] = ...;
  return arr;
}

Yes, the function type definition is ugly. James' typedef version reads more easily, but this is what's happening under the covers.

int main(void)
{
  char (*arr1)[SIZE];
  int i, j;

  arr1 = myFunction();
  ...
}

Upvotes: 1

James Curran
James Curran

Reputation: 103505

First of all, arr can not be a char**. It is an address, but it's not the address of a pointer -- it's the address of a char[SIZE].

I've always found it easier to deal with these by spliting the dimensions up using typedefs.

#define SIZE 3 
typedef char ROW[SIZE];   // a ROW type is an array of chars

ROW* MyFunction(void) 
{ 
     static ROW arr[SIZE]={  // arr is an array of ROW objects 
                                    {'A', 'B', 'C'}, 
                                    {'D', 'E', 'F'}, 
                                    {'G', 'H', 'I'} 
                                }; 
    return arr; 
} 

void main(void) 
{ 
    ROW* arr1 = NULL;
    // etc...

Upvotes: 4

Related Questions