0

In my c application I have the following declaration:

typedef double mat[MAX_SIZE][MAX_SIZE]; 

I have also a global variable:

mat aaa; 

in a function I want to do the following:

void func2(mat ccc) { ccc = aaa; } void func1() { mat bbb; func2(bbb); bbb[1][2] = 3; } 

I want the operations after func2() that I do on bbb to affect the global variable aaa, but they don't.

Any suggestions as to why the behavior is not what I expect?

1
  • 1
    Passing arrays to functions as arguments is not a good practice. They are passed as pointers and the length(s) is lost - which makes you to pass the length(s) also as argument(s). Commented Jan 5, 2012 at 19:21

4 Answers 4

1

You need to make bbb a pointer and send in the address of bbb.

void func1() { mat *bbb; func2(&bbb); (*bbb)[1][2] = 3; } 

And edit func2 like so:

void func2(mat **ccc){ *ccc=&aaa; } 
Sign up to request clarification or add additional context in comments.

3 Comments

Hm, as the question stands it seems like he wants the line bbb[1][2] = 3; somehow to affect aaa. Therefore, bbb must have a pointer type. Also, your function func1 will not work like you expect it.
*ccc=aaa; That won't work. Arrays cannot be copied by assignment like that.
Thanks. I just noticed that. Edited.
0

Your type mat isn't a pointer type, it's an array. You can't assign to array variables in C. The usual way to solve your problem is to use pointers:

void func1(void) { mat *bbb = &aaa; (*bbb)[1][2] = 3; } 

Comments

0

You mean, bbb[1][2] = 3; will be done on aaa? Then you would have to do like this:

mat aaa; mat* func2() { return &aaa; } void func1() { mat* bbb = func2(); (*bbb)[1][2] = 3; } 

1 Comment

I edited to use the right global variable name. Hope you don't mind.
0

There is a conceptual error in this code - an array expression may not be the target of an assignment. If you tried to write

void func1(void) { mat bbb; bbb = aaa; bbb[1][2] = 3; } 

the compiler would throw a diagnostic on the expression bbb = aaa (gcc gives an "incompatible types in assignment" diagnostic, since aaa is converted to a pointer type; more on that below). What you're trying to do by passing bbb to func2 is effectively the same thing, and is ultimately not going to work.

Let's get rid of the typedefs so we can see the actual types involved

double aaa[MAX_SIZE][MAX_SIZE]; ... void func2(double (*ccc)[MAX_SIZE]) { ccc = aaa; } void func1() { double bbb[MAX_SIZE][MAX_SIZE]; func2(bbb); bbb[1][2] = 3; } 

Unless it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be replaced with an expression of type "pointer to T" whose value is the address of the first element of the array. When you call func2, the expression bbb is converted from type "MAX_SIZE array of MAX_SIZE array of double" to "pointer to MAX_SIZE array of double"; hence the declaration of ccc as double (*ccc)[MAX_SIZE].

Similarly, in the line ccc = aaa in func2, the expression aaa is converted from type double [MAX_SIZE][MAX_SIZE] to double (*)[MAX_SIZE].

So far, func2 is kosher, because ccc is a pointer expression, not an array expression, so the assignment is allowed. ccc also happens to be a completely different entity from bbb (it receives a copy of the pointer value that bbb evaluates to), so writing to ccc has no effect on bbb. If you tried to get around that by passing a pointer to bbb, like so:

void func2(double (*ccc)[MAX_SIZE][MAX_SIZE]) { *ccc = aaa; } void func1(void) { double bbb[MAX_SIZE][MAX_SIZE]; func2(&bbb); bbb[1][2] = 3; } 

the compiler would throw the diagnostic on *ccc = aaa, either because *ccc has array type, or because the types of *ccc and aaa are incompatible (remember, aaa is converted to a pointer expression).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.