Archived

This topic is now archived and is closed to further replies.

mrbugg

C functions returning multidimensional arrays

Recommended Posts

I''ve looked everywhere and am baffled by this seemingly simple problem... I''m trying to create and pass a multidimensional array from a function to outside of it.
float* LoadLevel(void) {

	static float Level[36][6]; 
	int i; 
	int j;
	j = 0; 
	float x, y, z;
    x=0;
	y=0;
	z=0;

	FILE *LevelFile;
	LevelFile=fopen("level.txt", "r");

	for (i = 0; i < 36; i++) { 

	fscanf(LevelFile, "%f %f %f", x, y, z);

	Level[j] = x;
	Level[i][j+1] = y;
	Level[i][j+2] = z; 

	}

	return Level; 

}
 
I get this as an error:
error C2440: ''return'' : cannot convert from ''float [36][6]'' to ''float *''

Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
 
Is there a better way to do this? I kind of threw it together, so I''m not too sure. I''ve been trying to load a data file of float numbers that''s 36 columns deep and 6 wide. Any help is greatly appreciated!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Wouldn''t it just be easier to pass by reference?

Share this post


Link to post
Share on other sites
quote:
Original post by mrbugg
Is there a better way to do this? I kind of threw it together, so I''m not too sure. I''ve been trying to load a data file of float numbers that''s 36 columns deep and 6 wide.



Hmm... this is tough. I''m not sure that C allows you to return arrays. You could try changing the return type to float*[36][6] and returning &Level, or change the return type to float*[6] and leaving the return the same (this will lose dimension information, though). However, I''m not sure this is legal C.

Another option that would definitely work would be to wrap the array in a struct and return that (either a pointer to it or the struct itself, although the latter may be less efficient).

Or, you could change it to


static float **Level = NULL;
if (!Level) {
if (!(Level = malloc(36 * sizeof *Level))) {
// handle error
}
for (size_t k = 0; k < 36; k++) {
if (!(Level[k] = malloc(6 * sizeof **Level))) {
// handle error
}
for (size_t l = 0; l < 6; l++) {
Level[k][l] = 0; // or some other initial value
}
}
}


and change the return type to float**

Other than that, I don''t think you have many options (other than to restructure your program).

quote:
Oluseyi
Double indirection: change your return type to float **, and cast the return value to that type as well.

Note that you''ll lose all dimension information.



I don''t think that''ll work unless you recast it back to float[36][6] before using it. (float**)Level would be a pointer to a pointer to float. Thus, it''ll be interpretted as an array of pointers to floats, when in reality it''s an array of arrays of floats. That is, *((float*)Level) should be a valid floating point value, but probably isn''t a valid pointer.

Share this post


Link to post
Share on other sites
quote:
Original post by Way Walker
quote:
Oluseyi
Double indirection: change your return type to float **, and cast the return value to that type as well.

Note that you''ll lose all dimension information.


I don''t think that''ll work unless you recast it back to float[36][6] before using it. (float**)Level would be a pointer to a pointer to float. Thus, it''ll be interpretted as an array of pointers to floats, when in reality it''s an array of arrays of floats. That is, *((float*)Level) should be a valid floating point value, but probably isn''t a valid pointer.


It will work, there is no such thing as casting to float[36][6]... I think you are a little confused about how arrays work. float array[6] is the same as float *array = new float[6]; except that in the first case the memory will be freed automatically for you and the number between brackets must be a constant, in the second case you have to free the memory yourself with delete [] array.

I just wanted to add that you won''t lose any dimension information since there is none to start with.

Share this post


Link to post
Share on other sites
quote:
Original post by SpaceDude
It will work, there is no such thing as casting to float[36][6]... I think you are a little confused about how arrays work. float array[6] is the same as float *array = new float[6]; except that in the first case the memory will be freed automatically for you and the number between brackets must be a constant, in the second case you have to free the memory yourself with delete [] array.

I just wanted to add that you won't lose any dimension information since there is none to start with.


Nah, man, I think you are a little confused about how arrays work. Here's some code to try.


float array[10];
float *pointer = malloc(10 * sizeof *pointer);

size_t testArray = (sizeof array)/(sizeof *array);
size_t testpointer = (sizeof pointer)/(sizeof *pointer);

free(pointer);


Check the values of testArray and testpointer. testArray should be 10, I think testpointer will be 1 (that is, it will be the ratio of "size of pointer to float in bytes" to "size of float in bytes" rounded to an integer value).

If you're wondering about my use of malloc/free, please note that the question contains only valid C code, and the subject asks about C. Seems the poster is compiling in C++ mode, though. Anyway, feel free to use new/delete instead, results should be the same. (Also, in C (at least, on compilers that support the latest standard) in your first case you don't need a constant in the brackets)

EDIT: Changing examples midstream is a bad idea

[edited by - Way Walker on April 6, 2004 7:09:35 PM]

Share this post


Link to post
Share on other sites
Would creating a class that contains/creates a multidimensional array and its info be out of the question? Then you could just pass a pointer or reference to the class to a function... I ended up doing this mainly because I found that after creating a class I didn''t really need to pass the array to any functions outside the class and everywhere I needed the array values or array info, they were available through member functions. There are also other benefits to this I am sure but not wanting to insert foot in mouth I will stop before I say something stupid.


Evillive2
E-Mail

Share this post


Link to post
Share on other sites