Variable value assignment saved in wrong place?
I am relatively unfamiliar with C and this puzzles me right now. This is part of a much larger program, but I wrote this small program to depict the problem I am facing.
#include <stdio.h>
int main()
{
signed int tcodes[3][1];
tcodes[0][0] = 0;
tcodes[0][1] = 1000;
tcodes[1][0] = 1000;
tcodes[1][1] = 0;
tcodes[2][0] = 0;
tcodes[2][1] = 1000;
tcodes[3][0] = 1000;
tcodes[3][1] = 0;
int x, y, c;
for(c = 0; c <= 3; c++)
{
printf("%d %d %d\r\n", c, tcodes[c][0], tcodes[c][1]);
x = 20;
y = 30;
}
}
I expect this program to output:
0 0 1000
1 1000 0
2 0 1000
3 1000 0
But instead I get:
0 0 1000
1 1000 0
2 0 20
3 20 30
It does this for any number assigned to x and y. For some reason, x and y are overriding parts of the array in memory.
Can someone please explain what's going on?
Thanks!
a source to share
The other answers are correct, but to explain what is actually happening:
You have the following local declarations:
signed int tcodes[3][1];
int x, y, c;
The ones that are stored next to each other in the in-memory stack frame:
tcodes
x
y
z
tcodes
has 3 dots and is trying to write in tcodes[n]
just means find where tcodes
the memory points to and move to n
th (I'll ignore your second dimension since it was only 1). If you try to write to spot 3, it will move three points from the beginning tcodes
, although tcodes
not that big. Since it x
is located immediately after tcodes
, it tcodes[3]
will be in the spot , this memory will be overwritten, and the value x
will change. tcodes[4]
will overwrite y
and tcodes[5]
will overwrite z
. If you keep doingn
more (or negatively, which is legal), you can overwrite whatever you are allowed to access in memory, which can mess up your program in bad and hard-to-find ways.
a source to share
If you define an array like this:
int somearr[3];
You end up with an array containing 3 elements. Indexes start at form 0, so these items:
somearr[0]
somearr[1]
somearr[2]
On the stack are allocated arrays and other variables defined inside a function, for example in your code. It just so happens that the variables x and y are pushed onto the stack next to your array. If you try to access the elements
tcodes[3][0] or tcodes[3][1]
You are accessing the portion of the stack behind your array, and as your output shows, this is where the x and y variables are placed.
Actually the type definition
signed int tcodes[3][1];
creates an array containing 3 elements, each of which is also an array - an array containing one signed int. When you write tcodes [1] [1], you are accessing the non-existent "second" element of your second array. The memory space that the compiler accesses when it interprets tcodes [1] [1] overlaps with tcodes [2] [0];
a source to share
When you write the bounds of an array, you are writing to the memory allocated for the x and y variables on the stack. In this case, they are the same as tcodes [3] [0] == x and tcodes [3] [1] == y, since the addresses are the same. If you do this in a called function and the array is passed by reference, you may end up in stack corruption. The bottom line is that in C, arrays are 0-based.
a source to share