c beginner, vectors - c

I'm a c beginner and i've a problem (as usual). I wrote this simple program:
#include <stdio.h>
#define SIZE 10
main()
{
int vettore[9];
int contatore1,contatore2;
for(contatore1 = 0; contatore1 <= 9; ++contatore1)
{
vettore[contatore1] = contatore1*2;
}
printf("%d\n\n", vettore[9]);
for(contatore2 = 0; contatore2 < 10; ++contatore2)
{
printf("%d\n", vettore[contatore2]);
}
printf("\n%d\n", vettore[9]);
return 0;
}
The output of this program is:
18
0
2
4
6
8
10
12
14
16
9
10
Why the value of vettore[9] changes 3 times? And why it has the correct value only on the first line of the output? thank you :)

C arrays are zero based so valid indexes for a 9 element array are [0..8]. You are writing beyond the end of your array. This has undefined results but is likely corrupting the next stack variable.
In more detail... vettore has 9 elements, which can be accessed using vettore[0] ... vettore[8]. The final iteration of your first loop writes to vettore[9]. This accesses memory beyond the end of your array. This results in undefined behaviour (i.e. the C standard does not specify expected outcome here) but it is likely that the address of vettore[9] is the same as the address of contatore2, meaning that the latter variable is written to.
You have a similar problem in the next loop which prints more elements than vettore contains.
You can fix this by changing your loops to
for(contatore1 = 0; contatore1 < 9; ++contatore1)
for(contatore2 = 0; contatore2 < 9; ++contatore2)
Note that it would be safer if you changed to calculating the size of the array instead, by using sizeof(vettore)/sizeof(vettore[0]) in the exit test of your loops in place of hard-coding 9.

Your array vettore has 9 elements, but by referencing vettore[9], you're actually referencing the 10th element (since element indexing starts from 0). So it's some random location on the stack, without a well-defined value.
The solution is to index only up to vettore[8], or define vettore to have size 10.

check this out:
for(contatore2 = 0; contatore2 < 10; ++contatore2)
{
printf("%d\n", vettore[contatore2]);
}
you are displaying 11 elements of the vettore array (which is defined as a 9 ints array). I think that the error is in the random allocation on the stack

the vettore size as you defined is 9
int vettore[9];
and in your loop you start from 0 till 9 so you are playing with 10 elements of the array and not 9 (size of the array)
you should define the array with size 10
int vettore[10];

Arrays (i.e. "vectors") start at index zero NOT one; it's contents may be, for example, 5 but it will occupy index locations of 0,1,2,3,4....
[1][2][3][4][5] <- Five items
0 1 2 3 4 <- Their respective locations in the array
Same goes for visualizing characters in strings.....(technically the location in memory contains ASCII value-- look into that for fun ;) )
['c']['a']['t'] <- Three items
0 1 2 <- Their index location in the array
I suggest Kochan's C Programming book; great for starting out!!!

Related

Strange behaviour when finding largest number in Array [duplicate]

This question already has answers here:
Why does the indexing start with zero in 'C'?
(16 answers)
Closed 2 years ago.
Found some very bizarre behaviour when trying to brainstorm a problem:
Purpose of code:
Simple code to find the largest number in an array. I simply store the first index to a variable and compare it to every other index in the list. If another number is larger, that number replaces the number stored in my variable and the process repeats until the end of the list.
#include <stdio.h>
const int SIZE = 8;
int main(void)
{
int arr[] = {7, 3, 9, 14, 1, 27, 14, 2};
int largest;
largest = arr[0];
for (int i = 1; i <= SIZE; i++)
{
if (largest < arr[i])
{
largest = arr[i];
}
}
printf("The largest number in the array is %i\n", largest);
}
Weird behaviour:
This works, sometimes. Other times I get large numbers that give me the impression I've hit an area of memory I shouldn't have. I could understand if this happened every time but because it only happens every 2nd or 3rd time I compile the code I'm bewildered. The code doesn't change and yet the output does
Console Log:
~/pset3/plurality/ $ ./test
The largest number in the array is 1366797536
~/pset3/plurality/ $ ./test
The largest number in the array is 27
~/pset3/plurality/ $ ./test
The largest number in the array is 27
~/pset3/plurality/ $ ./test
The largest number in the array is 1773422672
~/pset3/plurality/ $
My ideas:
The loop somehow hits goes past the end of the array and sees that as the largest number. Again the bizarreness of this is that this only happens 50% of the time
Any ideas would be greatly appreciated.
Your loop is executing one time too many. The loop termination condition i <= SIZE will result in the loop body accessing arr[SIZE], which is outside of the arr array -- remember that C array indices start at 0.
Since the array is stored in the stack frame, your code will be fetching some garbage value from the stack located at the first address beyond the array. This garbage value could be anything, and so could be a large positive value, resulting in what you are seeing.
In C the arrays indices start from 0 to N - 1, with N begin the number of elements of that array, when you do:
for (int i = 1; i <= SIZE; i++)
you are accessing a position out of the allocate memory for that array, therefore you will be reading a random value from memory. Which is considered to be undefined behavior. Hence the reason why:
Again the bizarreness of this is that this only happens 50% of the
time
Sometimes the value that you will be reading from the position outside the array boundaries (i.e., will arr[i] with i = SIZE); will be bigger than the values that you have on the array, other times it will not. Hence, the name undefined behavior.
TLDR: You count i to 8 instead of 7 so you access a value out of bounds of the array. Remove the = sign in the declaration of the for loop.
You are counting from 1...8 in your for loop.
const int SIZE = 8;
…
for (int i = 1; i <= SIZE; i++)
Your Array has 8 values stored so you can access them with arr[0] … arr[7]
If you Access arr[8], which happens in the last Iteration of the for loop since you Count i up to 8 instead of 7 you Access a value out of Bounds, which gives you a kinda random value

C - how are dynamic arrays printed?

I'm a bit baffled with whether I'm printing my dynamic array correctly. I'm parsing an input file. Say the input file is:
x 6 9 15,
then my goal is to store 1, 2 and 3 into an array called x. It's doing exactly this. I've set the size of the array using:
arr = malloc(sizeof(int)*noValues);
(I also have int *arr declared as a global variable in my file)
where noValues is equal to the number of values encountered in the input file (in this case 3).
I then print the array using:
for (i = 0; i < noValues; i++) {
printf("arr[%d]: %d\n", j, arr[j]);
}
and get the following output:
arr[0]: 6
arr[1]: 9
arr[2]: 15
However, when I change the "noValues" in the for loop to 10, I get the following:
and get the output:
arr[0]: 6
arr[1]: 9
arr[2]: 15
arr[3]: 0
arr[4]: 0
arr[5]: 0
arr[6]: 49
arr[7]: 0
arr[8]: 17060496
arr[9]: 0
Why am I getting some non 0 values? Shouldn't they all be 0? Any clear-up would be appreciated. Is this normal C behaviour?
You are accessing "elements" out of the boundary of arr, this is undefined-behavior; that's why you get values that are seemingly random (but the application could just as well crash).
You're accessing past the end of the array, which is undefined behavior. Technically anything can happen when you do that, but there are two things that typically happen in practice: either the program will crash, or you'll just get the value of whatever bytes are located in memory past the end of the array. (But this isn't something that you can, or should, rely on.)
The uninitialized array behavior is not fix. The value of uninitialized array is zero ,garbage possible. if you want to get value zero of all the elements in the array then use bzero or memset function.

Strange array errors C

This may be due to my lack of understanding of C, but I'm getting some (what i would call) obscure errors when dealing with arrays:
Here is the code:
int * generateRandomArray(int numPageReplacements) {
// Seed random number generator
srand(time(NULL));
int * randPages = (int *)malloc(sizeof(int)*numPageReplacements);
for (int i = 0; i < numPageReplacements; i++) {
randPages[i] = rand() % 10; // generate (with uniform distribution) number 0 - 9
printf("%d ", randPages[i]); // for testing purposes
}
printf("\nRandomPages[3] = %d \n" ,randPages[3]);
return randPages; // return array pointer
}
Output:
7 9 4 6 4 6 5 7 6 3
RandomPages[3] = 6
Program ended with exit code: 0
If I run this back to back (take random numbers generated above) it will give 4 sometimes (what one would expect) and 6 at others (it's like it doesn't know the bounds of each array cell).
When I attempt to obtain the array from this function from the call:
int * ary = generateRandomArray(int numPageReplacements);
printf("Size of ary = %lu",sizeof(ary));
Output:
Size of ary = 8
It's equal to 8 no matter WHAT numPageReplacements is.
Compiler:
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix
Am I missing something here?
Calling sizeof on an pointer give you only the size of that pointer, which is what ary is. An array would be int ary[10];
You are working with dynamically allocated memory, not arrays. Sure, they work like arrays, kind of, because you can use [] to access its elements, but under the hood, they are very different beasts.
Just so you know, there is no way to find out how big an an array, or even if it is an array at all, as opposed to just the address of a single int, that's being passed to a function. A pointer merely stores a memory address. Interpreting what's at that address is up to the programmer. That's why C functions that accept arrays/buffers always take the size of that array/buffer as a separate parameter.
sizeof(ary), ary is an integer pointer and its size is 8 bytes(64bit) in a 64 bit machine that you are running.

Printing an empty 2d Array in C

I am writing a program that takes a 2D array and by use of a switch case, you can direct it to fill with random numbers and/or print the array among other things.
Before I fill the array with random numbers, I go to print the array just to see what it would do and I get this:
176185448 1 1 01430232144
32767180624652332767143023216832767
143023216832767 0 11430232192
32767176185344 1 0 14
143023220832767 0 0 0
0 0 0 0 0
This is my code for the print array function and I am passing plist from main:
void PrintArray2D(int plist[M][N])
{
size_t row, column; //counter
for (row = 0; row < M; ++row)
{
for (column = 0; column < N; ++column)
{
printf ("%5d" , plist[row][column]);
}
printf ("\n");
}
}
My Program is working fine otherwise. When I fill with random numbers and then print, my output is correct. The array size is 6 by 5. I'm just curious as to why, anything is being printed at all when it is supposed to be an empty array. And even more curious as to the specific output I am getting.
You are printing the value of uninitialized array. In this case the behavior of program is undefined. You may get any thing, either expected or unexpected result.
The value you are getting may be the some previous value stored at that location (called garbage value). Your program may gives erroneous result.
Are you initialising the array?
If not, you are more than likely getting the remains of whatever was in memory beforehand.
To initialise it to all zeros quickly, wherever it is defined have something like
int list[M][N] = {0};
Just a warning, the zero does not mean set all values to 0. It sets the first elements to the contents of the curly braces. So:
int values[M] = {1,2,3};
Would set the first three numbers to 1,2, and 3 and the remainder to zeros.
Variables in C must be initialized. If you don't initialize a variable (like an array) it contains some non-logic numbers (like address of a memory unit - the value which had been there before in that location of the memory)
The thing you're printing is that! you can't do this in some languages like Java, if you do so, you get an compilation error.
I hope this helps

Assigning a value to a variable gets stored in the wrong spot?

I'm relatively new to C, and this is baffling me right now. It's part of a much larger program, but I've written this little program to depict the problem I'm having.
#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'd 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 explain what's going on?
Thanks!
tcodes[3][0] = 1000;
tcodes[3][1] = 0;
are writing off the end of your array twice. [3] allocates slot ids 0-2 and [1] only allocates 1 actual slot [0].
Change your initialization of tcodes to signed int tcodes[4][2]; for 4 entries by 2 entries.
The other answers are right, but to help explain what's actually happening:
You have the following local declarations:
signed int tcodes[3][1];
int x, y, c;
Those get stored right next to each other in the stack frame in memory:
tcodes
x
y
z
tcodes has 3 spots, and trying to write to tcodes[n] just means to find where tcodes points to in memory and move over to the nth spot (I'm going to ignore your second dimension since it was just 1 anyway). If you try to write to spot 3, it's going to move over 3 spots from the beginning of tcodes, even though tcodes isn't that big. Since x is located right after tcodes, in the spot tcodes[3] would be in, that memory gets overwritten and the value of x changes. tcodes[4] would overwrite y, and tcodes[5] would overwrite z. If you kept making n bigger (or negative, which is legal), you could overwrite anything you're allowed to access in memory, which can screw up your program in bad and hard-to-find ways
Change it to this:
signed int tcodes[4][2];
If You define an array like this:
int somearr[3];
You get an array that has 3 elements. Indexes start form 0, so those elements are:
somearr[0]
somearr[1]
somearr[2]
Arrays and other variables defined inside a function, like in Your code, are allocated on the stack. It just so happens, that variables x and y are placed on the stack next to Your array. If you try to access elements
tcodes[3][0] or tcodes[3][1]
You access a part of a stack, that is behind Your array and, as Your output show, it's the spot, where variables x and y are placed.
In fact definition like this
signed int tcodes[3][1];
creates an array containing 3 elements, each of which is an array too - an array containing one signed int. When You write tcodes[1][1], You are accessing non-existing "second" element of your second array. The place in memory, that the compiler accesses when it interprets tcodes[1][1] overlaps with tcodes[2][0];
As you are writing beyond the array boundaries, you are writing on the memory allocated to x and y variables on stack. In this case, they happen to be same as tcodes[3][0] == x and tcodes[3][1] == y as the addresses are same.
If you are doing it in a called function and the array is passed by reference, you might end up in stack corruption.
The bottom line is that in C, arrays are 0 based.
You need to pay attention to the solution given by Robin Oster above. The other folks may be giving you "too much information". Just count the number of items in each dimension better, don't forget the zero'th item counts!

Resources