returning arrays from functions - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

returning arrays from functions

digitalranadigitalrana Posts: 19Member
im working on an assignment in C to hhandle Conway's game of life. This is basically a cellular simulation. It involves handling two dimensional arrays (i won't go into the details because that's not really important for the problem im having). Now according to the assignment specifications, there is a function (called life_invert) which must return the two dimensional array/matrix using the functions return mechanism and not using structs or pass-by-references.

This is what I've done so far:

the function for inverting is basicall as follows:

//CELL is defined previously as a char
//EP100_CELL_MAX_Y and .._X are previously defined as 512
CELL (**life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))
{
static CELL new_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y];
//
// Some of my processing on array new_pattern
//
return (CELL **)new_pattern;
}


my mainline has two arrays declared like the static one above (but non-static) called 'old' and 'new'

in the mainline i try to get the new one by doing:

new = life_invert(old);

This results in the error:
error, incompatible types in assignment.


i've even tried:
**new = life_invert(old)
//same error as before

i've tried doing the function declaration as:
CELL (*life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))[]

that comes up with errors about "life_invert declared as function which returns an array"


im quite confused about this because everything else works fine. I did it with the array within a struct and it was fine, i did it with the array as a second parameter and it worked fine, but according to the specifications, it must use the function return mechanism to return the array.

Does anyway know why this error is occuring? I can't seem to see where i've gone wrong here as far as logic and syntax is concerned but then again, im not yet a pro at C.

Can somebody please explain to me what i shud be doing or point me in the ryt direction?

Comments

  • DonotaloDonotalo Posts: 715Member
    : the function for inverting is basicall as follows:
    :
    : //CELL is defined previously as a char
    : //EP100_CELL_MAX_Y and .._X are previously defined as 512
    : CELL (**life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))
    : {
    : static CELL new_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y];
    : //
    : // Some of my processing on array new_pattern
    : //
    : return (CELL **)new_pattern;
    : }
    :
    :
    : my mainline has two arrays declared like the static one above (but non-static) called 'old' and 'new'
    :
    : in the mainline i try to get the new one by doing:
    :
    : new = life_invert(old);
    :
    : This results in the error:
    : error, incompatible types in assignment.
    :
    [purple]my following code compiles without an error:[code]
    #include
    using namespace std;

    char (**func()) {
    static char arr[30][60];

    return (char**) arr;
    }

    int main()
    {
    char **x;

    x = func();

    return 0;
    }
    [/code]
    so make sure u declare [b]new[/b] properly.
    [/purple]
    [hr][purple]~Donotalo()[/purple]

  • stephlstephl Posts: 422Member
    : im working on an assignment in C to hhandle Conway's game of life. This is basically a cellular simulation. It involves handling two dimensional arrays (i won't go into the details because that's not really important for the problem im having). Now according to the assignment specifications, there is a function (called life_invert) which must return the two dimensional array/matrix using the functions return mechanism and not using structs or pass-by-references.
    :
    : This is what I've done so far:
    :
    : the function for inverting is basicall as follows:
    :
    : //CELL is defined previously as a char
    : //EP100_CELL_MAX_Y and .._X are previously defined as 512
    : CELL (**life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))
    : {
    : static CELL new_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y];
    : //
    : // Some of my processing on array new_pattern
    : //
    : return (CELL **)new_pattern;
    : }
    :
    :
    : my mainline has two arrays declared like the static one above (but non-static) called 'old' and 'new'
    :
    : in the mainline i try to get the new one by doing:
    :
    : new = life_invert(old);
    :
    : This results in the error:
    : error, incompatible types in assignment.
    :
    :
    : i've even tried:
    : **new = life_invert(old)
    : //same error as before
    :
    : i've tried doing the function declaration as:
    : CELL (*life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))[]
    :
    : that comes up with errors about "life_invert declared as function which returns an array"
    :
    :
    : im quite confused about this because everything else works fine. I did it with the array within a struct and it was fine, i did it with the array as a second parameter and it worked fine, but according to the specifications, it must use the function return mechanism to return the array.
    :
    : Does anyway know why this error is occuring? I can't seem to see where i've gone wrong here as far as logic and syntax is concerned but then again, im not yet a pro at C.
    :
    : Can somebody please explain to me what i shud be doing or point me in the ryt direction?
    :
    The main error is that you mix two different types. life_invert() is passed a two dimensional array of chars. In memory, this array is stored this way:

    old_pattern[0][0] --> a single byte
    old_pattern[0][1]
    old_pattern[0][2]
    ...

    Your function should return such an array. However, you declared it to return a char **, which is not the same as a "true" bidimensional array like above. A char ** variable is in fact a one dimensional array containing pointers to chars (not chars).
    With the declaration
    [code]
    char **p;
    [/code]
    ,the array p contains:

    p[0] --> a pointer to char
    p[1] --> a pointer to char
    p[2] --> a pointer to char
    ...

    With a real bidimensional array, all the rows have the same length. It is not necessarily true with an array of pointers. When you define a bidimensional array to store 15*10 chars, what is allocated is a contiguous block of 150 chars. If you use a char ** variable, what is allocated first is a single pointer to pointer to char. You have to write the code to allocate the number of rows first. Then, for each row you allocate the number of elements you want. It may be different from one row to another. With the previous example, a true bidimensional array requires 150 bytes, while the pointer to pointer version needs 150 bytes for the chars + 15 pointers for the rows.

    [code]
    char array[15][10];
    char **p;
    char (*q)[10];
    char *r[15];
    [/code]
    Here array and p have incompatible types, but array and q have compatible types and p and r have compatible types.

    Steph
  • stephlstephl Posts: 422Member
    : : the function for inverting is basicall as follows:
    : :
    : : //CELL is defined previously as a char
    : : //EP100_CELL_MAX_Y and .._X are previously defined as 512
    : : CELL (**life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))
    : : {
    : : static CELL new_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y];
    : : //
    : : // Some of my processing on array new_pattern
    : : //
    : : return (CELL **)new_pattern;
    : : }
    : :
    : :
    : : my mainline has two arrays declared like the static one above (but non-static) called 'old' and 'new'
    : :
    : : in the mainline i try to get the new one by doing:
    : :
    : : new = life_invert(old);
    : :
    : : This results in the error:
    : : error, incompatible types in assignment.
    : :
    : [purple]my following code compiles without an error:[code]
    : #include
    : using namespace std;
    :
    : char (**func()) {
    : static char arr[30][60];
    :
    : return (char**) arr;
    : }
    :
    : int main()
    : {
    : char **x;
    :
    : x = func();
    :
    : return 0;
    : }
    : [/code]
    : so make sure u declare [b]new[/b] properly.
    : [/purple]
    : [hr][purple]~Donotalo()[/purple]
    :
    :
    No.
    It compiled because you forced the cast. Here you do not attempt to dereference x so your program won't crash even at run-time. But it would be different if you had attempted to do so and then tried to dereference *x. Have a look at my other reply if you want more information.

    Steph
  • DonotaloDonotalo Posts: 715Member
    : : im working on an assignment in C to hhandle Conway's game of life. This is basically a cellular simulation. It involves handling two dimensional arrays (i won't go into the details because that's not really important for the problem im having). Now according to the assignment specifications, there is a function (called life_invert) which must return the two dimensional array/matrix using the functions return mechanism and not using structs or pass-by-references.
    : :
    : : This is what I've done so far:
    : :
    : : the function for inverting is basicall as follows:
    : :
    : : //CELL is defined previously as a char
    : : //EP100_CELL_MAX_Y and .._X are previously defined as 512
    : : CELL (**life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))
    : : {
    : : static CELL new_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y];
    : : //
    : : // Some of my processing on array new_pattern
    : : //
    : : return (CELL **)new_pattern;
    : : }
    : :
    : :
    : : my mainline has two arrays declared like the static one above (but non-static) called 'old' and 'new'
    : :
    : : in the mainline i try to get the new one by doing:
    : :
    : : new = life_invert(old);
    : :
    : : This results in the error:
    : : error, incompatible types in assignment.
    : :
    : :
    : : i've even tried:
    : : **new = life_invert(old)
    : : //same error as before
    : :
    : : i've tried doing the function declaration as:
    : : CELL (*life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))[]
    : :
    : : that comes up with errors about "life_invert declared as function which returns an array"
    : :
    : :
    : : im quite confused about this because everything else works fine. I did it with the array within a struct and it was fine, i did it with the array as a second parameter and it worked fine, but according to the specifications, it must use the function return mechanism to return the array.
    : :
    : : Does anyway know why this error is occuring? I can't seem to see where i've gone wrong here as far as logic and syntax is concerned but then again, im not yet a pro at C.
    : :
    : : Can somebody please explain to me what i shud be doing or point me in the ryt direction?
    : :
    : The main error is that you mix two different types. life_invert() is passed a two dimensional array of chars. In memory, this array is stored this way:
    :
    : old_pattern[0][0] --> a single byte
    : old_pattern[0][1]
    : old_pattern[0][2]
    : ...
    :
    : Your function should return such an array. However, you declared it to return a char **, which is not the same as a "true" bidimensional array like above. A char ** variable is in fact a one dimensional array containing pointers to chars (not chars).
    : With the declaration
    : [code]
    : char **p;
    : [/code]
    : ,the array p contains:
    :
    : p[0] --> a pointer to char
    : p[1] --> a pointer to char
    : p[2] --> a pointer to char
    : ...
    :
    : With a real bidimensional array, all the rows have the same length. It is not necessarily true with an array of pointers. When you define a bidimensional array to store 15*10 chars, what is allocated is a contiguous block of 150 chars. If you use a char ** variable, what is allocated first is a single pointer to pointer to char. You have to write the code to allocate the number of rows first. Then, for each row you allocate the number of elements you want. It may be different from one row to another. With the previous example, a true bidimensional array requires 150 bytes, while the pointer to pointer version needs 150 bytes for the chars + 15 pointers for the rows.
    :
    : [code]
    : char array[15][10];
    : char **p;
    : char (*q)[10];
    : char *r[15];
    : [/code]
    : Here array and p have incompatible types, but array and q have compatible types and p and r have compatible types.
    :
    : Steph
    :
    [purple]
    nice explanation. :-)
    [/purple]
    [hr][purple]~Donotalo()[/purple]

  • stephlstephl Posts: 422Member
    : : : im working on an assignment in C to hhandle Conway's game of life. This is basically a cellular simulation. It involves handling two dimensional arrays (i won't go into the details because that's not really important for the problem im having). Now according to the assignment specifications, there is a function (called life_invert) which must return the two dimensional array/matrix using the functions return mechanism and not using structs or pass-by-references.
    : : :
    : : : This is what I've done so far:
    : : :
    : : : the function for inverting is basicall as follows:
    : : :
    : : : //CELL is defined previously as a char
    : : : //EP100_CELL_MAX_Y and .._X are previously defined as 512
    : : : CELL (**life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))
    : : : {
    : : : static CELL new_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y];
    : : : //
    : : : // Some of my processing on array new_pattern
    : : : //
    : : : return (CELL **)new_pattern;
    : : : }
    : : :
    : : :
    : : : my mainline has two arrays declared like the static one above (but non-static) called 'old' and 'new'
    : : :
    : : : in the mainline i try to get the new one by doing:
    : : :
    : : : new = life_invert(old);
    : : :
    : : : This results in the error:
    : : : error, incompatible types in assignment.
    : : :
    : : :
    : : : i've even tried:
    : : : **new = life_invert(old)
    : : : //same error as before
    : : :
    : : : i've tried doing the function declaration as:
    : : : CELL (*life_invert(CELL old_pattern[EP100_CELL_MAX_X][EP100_CELL_MAX_Y]))[]
    : : :
    : : : that comes up with errors about "life_invert declared as function which returns an array"
    : : :
    : : :
    : : : im quite confused about this because everything else works fine. I did it with the array within a struct and it was fine, i did it with the array as a second parameter and it worked fine, but according to the specifications, it must use the function return mechanism to return the array.
    : : :
    : : : Does anyway know why this error is occuring? I can't seem to see where i've gone wrong here as far as logic and syntax is concerned but then again, im not yet a pro at C.
    : : :
    : : : Can somebody please explain to me what i shud be doing or point me in the ryt direction?
    : : :
    : : The main error is that you mix two different types. life_invert() is passed a two dimensional array of chars. In memory, this array is stored this way:
    : :
    : : old_pattern[0][0] --> a single byte
    : : old_pattern[0][1]
    : : old_pattern[0][2]
    : : ...
    : :
    : : Your function should return such an array. However, you declared it to return a char **, which is not the same as a "true" bidimensional array like above. A char ** variable is in fact a one dimensional array containing pointers to chars (not chars).
    : : With the declaration
    : : [code]
    : : char **p;
    : : [/code]
    : : ,the array p contains:
    : :
    : : p[0] --> a pointer to char
    : : p[1] --> a pointer to char
    : : p[2] --> a pointer to char
    : : ...
    : :
    : : With a real bidimensional array, all the rows have the same length. It is not necessarily true with an array of pointers. When you define a bidimensional array to store 15*10 chars, what is allocated is a contiguous block of 150 chars. If you use a char ** variable, what is allocated first is a single pointer to pointer to char. You have to write the code to allocate the number of rows first. Then, for each row you allocate the number of elements you want. It may be different from one row to another. With the previous example, a true bidimensional array requires 150 bytes, while the pointer to pointer version needs 150 bytes for the chars + 15 pointers for the rows.
    : :
    : : [code]
    : : char array[15][10];
    : : char **p;
    : : char (*q)[10];
    : : char *r[15];
    : : [/code]
    : : Here array and p have incompatible types, but array and q have compatible types and p and r have compatible types.
    : :
    : : Steph
    : :
    : [purple]
    : nice explanation. :-)
    : [/purple]
    : [hr][purple]~Donotalo()[/purple]
    :
    :
    What do you mean with "nice explanation"? Was my explanation understandable or not?

    Steph
  • DonotaloDonotalo Posts: 715Member
    : : [purple]
    : : nice explanation. :-)
    : : [/purple]
    : : [hr][purple]~Donotalo()[/purple]
    : :
    : :
    : What do you mean with "nice explanation"? Was my explanation understandable or not?
    :
    : Steph
    :
    [purple]ur explanation enrich my knowledge. i like the details u provided. that was understandable of course.
    [/purple]
    [hr][purple]~Donotalo()[/purple]

Sign In or Register to comment.