0

I have looked for this for quite sometime but haven't found a satisfactory solution. How do I return a double dimensional array in a C function?

float **KE()
{
    float K[2][2]={{1,2},{3,4}};
    return K;
}

For the above code, I get the error

error: cannot convert 'float<*>[2]' to 'float**' in return
2
  • 1
    You're returning a stack variable, is not gonna work. Commented Jul 5, 2013 at 21:27
  • Why are func name and variable name same? Commented Jul 5, 2013 at 21:28

2 Answers 2

2

Put it in a struct:

struct dar { float data[2][2]; };

struct dar K()
{
    struct dar x = { { { 1, 2 }, { 3, 4 } } };
    return x;
}

Usage:

struct dar x = K();

printf("%f %f\n", x.data[0][0] + x.data[0][1], x.data[1][0] + x.data[1][1]);
Sign up to request clarification or add additional context in comments.

8 Comments

You don't wanna do this with large arrays, copying all of the data.
@meaning-matters: No, but I'd definitely do it with a 2-by-2 array.
True, it's a nice trick :-)
@meaning-matters: (And you can go and teach the OP manual memory management :-) I think this solution might actually scale to reasonable "beginner's first program" sizes without noticeable bottlenecking, and it saves everyone a whole lot of headache...)
So primitive 2D is not allowed but representative struct is ok?
|
1

You can't return an array from a function. Arrays are not copyable. You can wrap it into a struct, but in general case passing around a potentially large object by value is not a good idea.

What you can do is return a pointer to an array from function. But for that you have to make sure the object that pointer points to continues to live when the function exits. A popular idiom is to pass the destination array from the caller code and fill it inside the function

float (*KE)(float (*dst)[2][2])[2][2]
{
  (*dst)[0][0] = 1;
  (*dst)[0][1] = 2;
  (*dst)[1][0] = 3;
  (*dst)[1][1] = 4;
  return dst;
}

...
float array[2][2];
KE(&array);

Note that in this case it is not necessary to return the pointer to the array from the function, since the resultant array is already known to the caller. But I did it anyway to further complicate the function declaration syntax and make it more difficult to read.

You can always de-obfuscate it by defining a typedef name for the array type

typedef float F22[2][2];

F22* KE(F22* dst)
{
  ...
}

Alternatively, to preserve the neatness of the aggregate initialization syntax, you can implement the function body as

F22* KE(F22* dst)
{
  const F22 K = { {1, 2}, {3, 4} };
  memcpy(dst, &K, sizeof *dst);
  return dst;
}

or even as

F22* KE(F22* dst)
{
  return memcpy(dst, &(const F22) { {1, 2}, {3, 4} }, sizeof *dst);
}

5 Comments

Do you want a +1 for not using a typedef, or a -1 for not using a typedef?
@Kerrek SB: Wait, I'm still working...
@KerrekSB That's the comment of my life.
@Kerrek SB: Don't tell me though. I wanna know how it feels to be that cat.
Schrödinger's typedef: It may be an array, or it may be a pointer. You can't tell until you compile.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.