breheme
breheme

Reputation: 41

Probably a silly,often asked, mistake involving arrays in C

I am very new to C and I am having problems with the following. I initialize the arrays:

double Cx[101];
for(int i=0; i<101; i++){
  Cx[i]=-5+i*0.1;
}

double Q[2][101];
double y[101];

and I have the following functions outside the main method:

double InitHeight(double g, double dx, double x){
  return 3;
}

double InitMom(double g, double dx, double x){
 return 2;
}

double plainTopo(double x){
 return x*10;
}

Now, in the main method I do the following:

double g=1;
double dx=0.1;
for(int i=0; i<101; i++){
  Q[1][i] = InitHeight(g,dx,Cx[i]);
  Q[2][i] = InitMom(g,dx,Cx[i]);
  y[i] = plainTopo(Cx[i]);
}

So, my problem is that the original values of the Cx array get modified. Here is a portion of the original Cx:

-5.000000
-4.900000
-4.800000
-4.700000
-4.600000
-4.500000
-4.400000
...

and after I run the the code this is what I get:

   Cx[]   Q[1][]   Q[2][]     y[]
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000

I can't for the life of me see why the Cx array gets modified. I have tried to use pointers instead with the same results, also tried to do double x = Cx[i] in the loop and then pass x to the functions but again Cx gets change.

Any help would be greatly appreciated it.

Upvotes: 3

Views: 95

Answers (4)

paxdiablo
paxdiablo

Reputation: 881633

double Q[2][101];
:
Q[2][i] = InitMom(g,dx,Cx[i]);

Your corruption is happening because the legal indexes for Q do not include Q[2][...].

You seem to know this since you iterate i from 0 to 100 inclusive, for the Cx[101] array so it appears to be just a temporary mistake - it's the same rule for all dimensions of an array.

Upvotes: 1

RoneRackal
RoneRackal

Reputation: 1233

double g=1;
double dx=0.1;
for(int i=0; i<101; i++){
  Q[1][i] = InitHeight(g,dx,Cx[i]);
  Q[2][i] = InitMom(g,dx,Cx[i]);
  y[i] = plainTopo(Cx[i]);
}

You do not have a Q[2][i] available, so it's probably overwriting into your Cx array

I think what you meant was

Q[0][i] = InitHeight(g,dx,Cx[i]);
Q[1][i] = InitMom(g,dx,Cx[i]);

Upvotes: 1

Adam Mihalcin
Adam Mihalcin

Reputation: 14458

You're indexing into Q incorrectly. Array indices in C start at 0, not 1. So you should have

double g=1;
double dx=0.1;
for(int i=0; i<101; i++){
  Q[0][i] = InitHeight(g,dx,Cx[i]); /* Used to be Q[1][i] */
  Q[1][i] = InitMom(g,dx,Cx[i]); /* Used to be Q[2][i] */
  y[i] = plainTopo(Cx[i]);
}

As for why Cx gets changed, accessing an out-of-bounds item in an array causes undefined behavior, which means that the C compiler can do anything it feels like. Your particular compiler generates assignments into Cx. Technically, this is because of the way arrays are laid out on the stack, but the compiler is not required to do the same thing that your compiler does, and can instead choose to cause your program to crash (this is the best case, because it helps you find the bug), write over top of other data (this is what you are seeing), or delete all your files (no compiler I know of actually does this). Really, the compiler has complete freedom to cause as much havoc as it feels like whenever undefined behavior occurs, and one such situation is when you access an out-of-bounds array index.

Upvotes: 6

hmjd
hmjd

Reputation: 121971

This going beyond the bounds of the array Q, causing undefined behaviour:

Q[1][i] = InitHeight(g,dx,Cx[i]);
Q[2][i] = InitMom(g,dx,Cx[i]);

must be Q[0] and Q[1] as Q is defined as:

double Q[2][101];

The other indexing in your code indicates you are aware that array indexes are zero-based and run from 0 to N - 1 where N is the number of elements in the array.

Upvotes: 5

Related Questions