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

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 :)

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

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}

C for loop continues incrementation

Newb here.
I'm probably missing something trivial but:
Here's the thing: http://i.imgur.com/8BmPci5.png
#include <stdio.h>
#include <stdlib.h>
int main()
{
//Sort Numbers (zuerst)
int numbers [10];
int i,j;
j = 0;
int read;
printf("Input numbers: \n");
for (i=0;i<10;i++) {
scanf("%d",&read);
if (read == 27) {
break;
} else {
numbers[i] = read;
j++;
}
}
printf("j is: %d, i is: %d\n", j, i);
for (i=0;i<j;i++) {
printf("numbers[%d] is: %d\n", i, numbers[i]);
}
return 0;
}
Output:
Input numbers:
1
2
3
^[
j is: 10, i is: 10
numbers[0] is: 1
numbers[1] is: 2
numbers[2] is: 3
numbers[3] is: 3
numbers[4] is: 3
numbers[5] is: 3
numbers[6] is: 3
numbers[7] is: 3
numbers[8] is: 3
numbers[9] is: 3
I have a for loop (goes from 0 to <10). I also have a scanf inside wich scans for an int. If it ain't ESC (ASCII 27), then it puts it into an array and it increments the value of j. If it's an ESC, it ('s supposed to) break (exit the loop). Later, only j (or j-1) number of array items would be printed.
Issue: j (and i too) increments to 10, even if break is called at ~ i = 3 or 4.
Break supposed to exit the for loop without doing anything after it's called, right? Quote from BeginnersBook.com:
It is used to come out of the loop instantly. When a break statement is encountered inside a loop, the control directly comes out of loop and the loop gets terminated. It is used with if statement, whenever used inside loop.
What's wrong with my code? Thanks in advance.
You're being naughty in that you're not checking the return value of scanf, which will tell you the number of variables that were successfully populated. In your case, you want that to be 1 to signal that something was read into your variable read.
If you try to pass \033 (ASCII encoded ESC), then scanf will fail to parse that to an int. Then the previous value of read will be retained (which could give you undefined effects if it hasn't yet been set to anything), and read == 27 will almost certainly be 0. That behaviour accounts for the output you are observing.
If scanf does fail, you could try reading a char from the stream, and check if that is equal to \033.

C runtime error during recursive function call

So I have a program to find the total number of ways in which an integer N can be expressed as the sum of "n" integers.
For example, 10 can be expressed as a combination of 2,3 and 5 as follows-
10 = 5 + 5
10 = 5 + 3 + 2
10 = 3 + 3 + 2 + 2
10 = 2 + 2 + 2 + 2 + 2
#include<stdio.h>
#include<stdlib.h>
int ways(int,int*,int);
int main() {
int n,num; //n is number of possible integers
scanf("%d",&n);
int*curr=(int*)malloc(n*sizeof(int)); //dynamically allocated array that stores all "n" integers in array form
for(int i=0;i<n;i++) {
scanf("%d",curr+i);
}
int t,N; //t is number of test cases
scanf("%d",&t);
while(t--) {
scanf("%d",&N); //for each test case, scans the number N that needs to be expressed as a sum of combinations those "n" integers
num=ways(N,curr,n);
printf("%d\n",num);
}
return 0;
}
int ways(int N,int*p,int size) {
int flag=1;
for(int i=0;i<size;i++) {
if(N/(*(p+i))!=0) {
flag=0;
break;
}
//Above loop says that if number N is less than all of the "n" integers, it
cannot be expressed as their sum. Hence, 0 will be returned if flag is 1
}
if(flag==1)
return 0;
if(N==0)
return 1;
int num=0,temp;
for(int i=0;i<size;i++) {
temp=*(p+i);
num=num+ways(N-temp,p,size); //GETTING RUNTIME ERROR AT THIS LINE
}
return num;
}
The program is getting SIGSEGV error at the recursive function call even for very small depth of recursion
In the first i loop in ways, you seem to be looking for a value in
array p that is smaller than N (though division is a horribly
inefficient way to test). Having found one, you do other things, then
use another i loop, losing the value of i you found in the first
one, and call ways recursively.
Now, note that you do no testing in the second loop. It’s entirely
possible to subtract something from N that is larger than N, get a
negative result, and pass that. This would cause infinite recursion, no?
A SIGSEGV error is a Segmentation fault error, which means that you are trying to access a memory location out of your programs reach.
This is most common due to de-referencing a null pointer or going over in your for loop. Try checking the logic of your code.
I think when you are typing *(p + 1), you are going out of bounds at some point. Try debugging with breakpoints or by outputting the value of *(p+1) in the for loop.

Why is the seventh variable 6 in my program?

#include <stdio.h>
int main(void) {
int n,i;
int str[n];
scanf("%d\n",&n);
for(i=0;i<=n;i++)
{
scanf("%d",&str[i]);
printf("%d th %d\n",i,n);
}
return 0;
}
Input:
10
8 9 2 1 4 10 7 6 8 7
Output:
0 th 10
1 th 10
2 th 10
3 th 10
4 th 10
5 th 10
6 th 10
7 th 6
Why is 6 in the output?
This is really strange code with undefined behavior. What do you expect this:
int n; // No value!
int str[n];
To do? You get an array whose length is unknown since n has no value at the point of the str declaration.
If you expected the compiler to "time-travel" back to the str[n] line magically when n is given a value by scanf(), then ... that's not how Co works, and you should really read up on the language a bit more. And compile with all warnings you can get from your environment.
As an extra detail, even if it were fixed so that n had a value, the for loop overruns the array and gives you undefined behavior again.
For an array of size m, the loop header should read
for (size_t i = 0; i < m; ++i)
Since indexing is 0-based, you cannot index at m, that's outside the array.
In your code
int n,i;
int str[n];
you're using n while it has indeterminate value, unitialized. It invokes undefined behavior.
To elaborate, n being an automatic local variable, unless initialized explicitly, contains indeterminate value.
Solution: You need to define int str[n]; after you has taken the value from user (and sanitized).
After that, there's once more issue, your loop runs off-by-one for the array. C uses 0-based array indexing, so, for an array of size n, the valid indexes will be 0 to n-1. You loop construct should be
for(i=0; i<n; i++)
The value for the size of the string str[] is not yet defined. You need to have initialized this value before declaring a string/array.
If you're using gcc to compile, try including the -Wall flag in your compile line to catch errors like this.

Resources