Why is this code outOfBound? - c

Here is a problem I met the other day in a interview, would someone tell me the "truth" behind this "simple" code?
#include<stdio.h>
int main()
{
int a[]={1,2,3};
for(int i=0; i<=3; i++){
a[i]=0;
printf("%d\n", i);
}
return 0;
}

Everything will be right if <= is replaced by < as it is causing array out of bound index error and will print value
0
1
2
3
although the value of the array content will be 0 every time

The loop variable i takes on values 0, 1, 2, and 3. Unfortunately, 3 is an out-of-bounds index for array a, which only has length 3 (legal indices 0, 1, and 2). To avoid an out-of-bounds array access, the loop control should be
for(int i=0; i<3; i++){
Note the use of < instead of <=. As an interview question, the goal was to test whether you noticed this very common kind of off-by-one error.

Related

Enter unknown number of array values in C/C++ has strange behaviour

I need to populate an array of integers with an unknown number of elements. I am using a while loop to input values and exit the loop as a non integer value is entered. Outside the loop an integer j is initialized at 0 and used to address array elements inside the loop. At each round of the loop I check the value of j before and after the input value is assigned to array element v[j], then j is incremented.
Depending on the size chosen for the array in the declaration, (in the example below v[8]), index j is unexpectedly affected by the assignment itself: in the example below when j equals 11 before the assignment it becomes 2 after the assignment, thereafter messing it all up. As a result the code fails to assign the correct input values to the array.
I am surely lacking some deeper knowledge about C/C++ array management... anyone can help to to fill the gap explaining the apparently strange behaviour of my code?
#include <stdio.h>
int main()
{
int j = 0, m, v[8];
printf("Enter an integer: to finish enter x\n");
while (scanf("%d", &m))
{
printf("j before assignment:%d - ", j);
v[j] = m;
printf("j after assignment:%d - ", j);
printf("v[j] after assignment:%d\n", v[j]);
j++;
}
return 0;
}
You write beyond the array boundaries of v. To avoid this, check j in a for loop, e.g. replace while (...) with
for (j = 0; j < 8 && scanf("%d", &m) == 1; ++j) {
// ...
}
This way, the loop stops after the end of the array (v[7]) is reached.
To comment the "strange" behaviour, read about stack and stack layout, e.g. Does stack grow upward or downward?
As always, check the C tag wiki and the books list The Definitive C Book Guide and List

Specific for-loop for a simple sort algorithm

this is a simple code for sorting a table from max to min. I am confused because my professor used for(i=0; i<10-1; i++) and I saw that it works fine with for(i=0; i<10; i++). Can please someone tell me the difference?
Thanks for your time, appreciate your help.
int a[10];
int i, j, t;
for(i=0; i<10; i++)
{
scanf("%d", &a[i]);
}
for(i=0; i<10-1; i++)
{
for(j=i+1; j<10; j++)
{
if (a[i]>a[j])
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
for(i=0; i<10; i++)
{
printf("%d\n", a[i]);
}
Your professor is correct, although your way does work too; it's just clumsier:
Given that the starting value of j is i + 1, in order to avoid a out of bounds access to the array a (the behaviour of which is undefined), you need to constrain i to be less than 9 and i + 1 to be less than 10. Essentially your professor constrains the former, but you constrain the latter.
The bubble sort works this way as sortedness is established once the outer loop has processed the penultimate element.
Converting my comment:
Usually, these kind of algorithms do not stop at the last one, but an element before. In fact, at that point, the nth-1 element is already sorted with respect of the nth one. So, both works, but the "-1" is more efficient because you skip a useless iteration.
In case of for(i=0; i<10; i++) you get one additional iteration of the external loop, in wich i is equal 9. But then in the internal loop j is equal 10 at once, condition j < 10 isn't met, and the internal loop terminates without executing its body.

Trying to make a function which squares all values in an array. Getting strange number on the last value

int squaring_function (int *array, int i);
int main()
{
int array[5];
int i;
for(i=0; (i <= 5) ; i++)
{
array[i] = i;
printf("\nArray value %d is %d",i,array[i]);
}
for(i=0; (i <= 5) ; i++)
{
array[i] = (squaring_function(array, i));
printf("\nSquared array value %d is %d",i,array[i]);
}
return 0;
}
int squaring_function (int *array, int i)
{
return pow((array[i]),2);
}
I'm trying to use this squaring_function to square each value in turn in my array (containing integers 0 to 5). It seems to work however the last value (which should be 5)^2 is not coming up as 25. cmd window
I have tried reducing the array size to 5 (so the last value is 4) however this prints an incorrect number also.
I'm quite new to C and don't understand why this last value is failing.
I'm aware I could do this without a separate function however I'd quite like to learn why this isn't working.
Any help would be much appreciated.
Thanks,
Dan.
There are 2 bugs in your code. First is that you're accessing array out of bounds. The memory rule is that with n elements the indices must be smaller than n, hence < 5, not <= 5. And if you want to count up to 5, then you must declare
int array[6];
The other problem is that your code calculates pow(5, 2) as 24.99999999 which gets truncated to 24. The number 24 went to the memory location immediately after array overwriting i; which then lead to array[i] evaluating to array[24] which happened to be all zeroes.
Use array[i] * array[i] instead of pow to ensure that the calculation is done with integers.
The code
int array[5];
for(int i=0; (i <= 5) ; i++)
exceeds array bounds and introduces undefined behaviour. Note that 0..5 are actually 6 values, not 5. If you though see some "meaningful" output, well - good or bad luck - it's just the result of undefined behaviour, which can be everything (including sometimes meaningful values).
Your array isn't big enough to hold all the values.
An array of size 5 has indexes from 0 - 4. So array[5] is off the end of the array. Reading or writing past the end of an array invokes undefined behavior.
Increase the size of the array to 6 to fit the values you want.
int array[6];
The other answers show the flaws in the posted code.
If your goal is to square each element of an array, you can either write a function which square a value
void square(int *x)
{
*x *= *x;
}
and apply it to every element of an array or write a function which takes an entire array as an input and perform that transformation:
void square_array(int size, int arr[size])
{
for (int i = 0; i < size; ++i)
{
arr[i] *= arr[i];
}
}
// ... where given an array like
int nums[5] = {1, 2, 3, 4, 5};
// you can call it like this
square_array(5, nums); // -> {1, 4, 9, 16, 25}

For Loop in C does not work as Expected

I don't understand the flow of the following for loop: it becomes an infinite loop. I am using ubuntu 12.04. Am I doing anything wrong here?
#include <stdio.h>
main()
{
int k,a[10];
for(k=0; k<=10; k++)
{
a[k]=1;
printf("k = %d\n",k);
}
}
Once k == 9, it automatically changes to 1. I don't know why it behaves like this. What am I doing wrong?
for(k=0; k<=10; k++)
This access out of bound index . a[10](indexing start with 0 therefore valid index 0-9) is out of bound and invoke undefined behaviour.
loop should be this -
for(k=0; k<10; k++)
Your operating system doesn't affect the way the loop is processed. What you need is a way to handle the integer variable "k" and inside the loop, you need to make "k" greater than 10 for the loop to exit properly. So I made K increment so that each element of the integer array "a" contains the value 1.
#include <stdio.h>
int main()
{
int k,a[11];
for(k=0; k<=10; k++)
{
a[k]=1;
printf("k = %d\n",k);
k++;
}
return 0;
}
Actually array index starts from 0. So if you have an array "a" with 10 members in it, then the members will be
1st member - a[0];
2nd member - a[1]; 3rd member - a[2]; ... ... ... 10th member - a[9]
So, you can't have a member a[10]. But in your for loop you started k from 0 and incremented it to 10. But a[10] was not present in the array and this caused the infinite loop. To solve this problem, just use "k<10" as your loop condition. Your code should look like this now:
#include <stdio.h>
main()
{
int k,a[10];
for(k=0; k<10; k++)
{
a[k]=1;
printf("k = %d\n",k);
}
}
The reason k is becoming 1 after 9 is that for some reason k is situated right after the memory range of a. So, when you change a[10] to 1, it actually changes the value of k. So, you get 1 as the value of k.

How could it be possible to read and write past the array

Output of the program:
#include <stdio.h>
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d",&size);
int b[size],i = 0;
printf("Enter %d integers to be printed: ",size);
while(i++ < size)
{
scanf("%d",&b[i]);
printf("%d %d\n", i, b[i]);
}
return 0;
}
for size = 5 and input numbers :
0 1 2 3 4
is
1 0
2 1
3 2
4 3
5 4
where first column is for i and second for elements of array b.
It is clear that i in the loop while(i++ < size) { incremented to 1 before entering the loop. This loop should have to store/print the value at/of b[1], b[2], b[3], b[4] but not b[5] as loop will terminate at i = 5.
How this code is printing the value of b[5]?
I have tested it for different array size and it is not printing any garbage value.
By reading and writing past the array, your program invokes undefined behavior. It doesn't mean that it has to crash or print garbage values, it can pretend working fine. Apparently, that's what is happening in this case.
In your loop, the condition i < size is checked before i is incremented. But, i is incremented before entering the body of the loop and not after it, so it is possible to access b[5] in this case, as i would be incremented after checking i < size with i=4. You do not want that, as this causes undefined program behavior.
If you try to access an element in the array which does not exist, e.g. array[size], you are accessing the next spot in the memory right after the array. In this case you are lucky, but if this meant you were accessing a part of the memory where your program isn't allowed to do so, you'd get a segmentation fault.
you could use a for cycle instead of a while so instead of while(i++<size)you could use for(i = 0; i < size; i++) that should solve your problem my friend :)

Resources