Why this value is changing? - c

I've just started learning C language. so I was doing some exercises and I had a problem with this one.
The code:
#include <stdio.h>
#include <math.h>
main()
{
double l[2];
double s, v, d;
int i;
for (i = 0; i < 3 && l[i] >= 0; i++)
{
scanf("%lf", &l[i]);
if ( l[i] < 0)
{
printf("Please type a positive value\n");
l[i+1]=-1;
}
}
if (l[0] >= 0 && l[1] >= 0 && l[2] >= 0)
{
s = 2 * ((l[0] * l[1]) + (l[0] * l[2]) + (l[1] * l[2]));
v = l[0] * l[1] * l[2];
d = sqrt(pow(l[0],2)+pow(l[1],2)+pow(l[2],2));
printf("%.2f\n%.2f\n%.2f\n", s, v, d);
}
}
The output gives right value for "s", but it changes l[2] value after "s" is stored, consequently it gives me wrong values for "v" and "d". I dont understand why l[2] is changing, anyone could help?

The definition
double l[2];
defines an array with space for 2 values of type double.
The array elements can be accessed with l[0] and l[1]. Accessing l[2] (as you are doing) is an error.

Accessing l[2] results in undefined behavior. Arrays in C are 0-indexed and l only contains two elements, i.e., l[0] and l[1]. Your loop should be:
for (i = 0; i < 2 && l[i] >= 0; i++)
And you should probably just store the size in a constant.

Your program invokes undefined behavior;
1. You are reading/writing to an unallocated memory location.
2. In your for loop you are reading uninitialized variable.

Yeah, the answer for why the value is changing would be that since the memory location at l[2] is not allocated to your program, it is probably allocated to some other program, which is changing it's value. Even when you are reading some stuff into it, some other program is trying to change it again.
Again, there is still a fair chance that the code would work fine if you are not running many processes. This is because, if the memory block containing l[2] is empty, it doesn't change over time.
However, accessing variables out of your scope is a bad practice and would give you errors in other compilers.

error is in accessing l[2]
if (l[0] >= 0 && l[1] >= 0 && l[2] >= 0)

Related

Program is working on code block but not in hacker rank

This piece of code works returns correct output in codeblock but not on hacker rank. I am not getting the issue?
#include <stdio.h>
int main()
{
int num,i;
long long unsigned int *num_alloc, FinalSum = 0;
num_alloc=(int*)malloc(sizeof(int)*num);
scanf("%d",&num);
for ( i=0;i<num;i++)
{
scanf("%llu",&num_alloc[num]);
FinalSum =FinalSum + num_alloc[num];
}
printf("%llu",FinalSum);
return 0;
}
let's walk through your code:
malloc(sizeof(int) * num), what is the value of num ?
scanf("%d",num), check the return value of scanf ( number of element successfully parsed by scanf )
for( i = 0 ; i < num; i++ ), loop with i from 0 to num
scanf("%llu",&num_alloc[num]), read number and store it in num_alloc[num] ( indices of array in C start from 0 )
FinalSum = FinalSum + num_alloc[num], add num_alloc[num] to FinalSum ( see #4 )
end loop
I provided some advice to fix your code. But additionally do you need to store each values that are read until the end of the program ?
Also, 'malloc' is a function of 'stdlib.h' and you didn't include that header file.
Before allocating memory for num_alloc, you must initialize the num variable. If not, memory for num_alloc will be allocated with a trash size, so you've got undefined behavior.
A number of things are jumping out at me about your code. You are allocating memory for num integers, when num is uninitialized. It is given an undefined trash value. See undefined behavior. You must put your scanf statement before your malloc, because as it stands right now your code does not make sense.
for ( i=0;i<num;i++)
{
scanf("%llu",&num_alloc[num]);
FinalSum =FinalSum + num_alloc[num];
}
For each loop iteration, you are accessing the numth element of your array. This is not possible as num_alloc should be an array of num ints, and array indexes in C start at 0. But what I'm pretty sure what you meant to do is this. With your code, you would have been assigning the same value over and over again.
for (i = 0; i < num; i++) {
scanf("%llu", &num_alloc[i]);
FinalSum += num_alloc[i];
}
You must also free() any memory you allocate on the heap with malloc().
free(num_alloc);

Initializing int Array in C Without Assigning Values

I'm working through K&R exercise 1-13, and I forgot to set the elements in my array to 0. To my surprise, the last value that I got when printing the array was 32767; subsequent tests have different element values for the array, some different, and some not.
I'd like to know why this is happening. If it's highly complex, then what's going on in simple terms?
#include <stdio.h>
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
/* print the length of words as input to a histogram with horizontal bars */
int main() {
int c, i;
int state = OUT;
int accum = 0;
int nchar[10];
while ((c = getchar()) != EOF) {
if (c != ' ' && c != '\n' && c != '\t') {
state = IN;
++accum;
}
else {
state = OUT;
++nchar[accum];
accum = 0;
}
}
for (i = 0; i < 10; ++i)
printf("%d\n", nchar[i]);
return 0;
}
Input & Corresponding Output:
hello codes
4195584
0
0
0
4196032
2
4195584
0
-1608045280
32767
When the array is created, the compiler claims memory on the stack. Data is written to that memory location, if you are initializing the array or (in general) assigning values to it.
If you do not initialize anything, just memory is claimed, which was already used before for something else. The stack is not zeroed after data gets removed, because it would waste too much processor time and the RAM is getting filled with data again anyway.
That's simply what happens when you don't initialize your memory. You get whatever was there before your program claimed it...
Whatever the program that previously ran in your address space put there. So if a program put, say, 77, at address 0xabcd5657, and then you read that address, you'd get 77. This is because C does not zero initialize memory for you, although you can yourself with memset:
memset(nchar, 0, 10);

Segmentation Fault(core dumped) when an int variable is initialized

Segmentation fault appearing due to initializing of the variable 'b'. Someone please help me on this.
#include "stdio.h"
#include "string.h"
int main(){
char *z[20], *x, *y = {"abcd"};
int i, j, b = 4;
for (i = 0 ; i < 4 ; i++) {
for (j = 0 ; j < b ; j++) {
*(x + j) = *(y + j + i);
z[i] = x;
printf("%s", z[i]);
printf("\n");
}
b--;
}
return 0;
}
You dereference x which is not initialized anywhere and hence is an invalid pointer
*(x + j) = *(y + j + i);
Possible solution:
Declare x as an array, like
char x[5];
and, nul terminate it before printing it, like
x[j] = y[i + j];
x[1 + j] = '\0';
One more thing, is that every z[i] that is initialized, will point to the same data, i.e. to the array x if you apply my suggested solution.
You already got the answer from Mr. Iharob for your question, just to elaborate a bit, I though of adding mine.
In your question, you mentioned like
...when an int variable is initialized
This statement is wrong. There is no issue with int variable initializations (i = 0, j = 0 and b = 4). The issue here is with the inappropriate usage of x.
In your code, x is of type char *, i.e., it is a pointer to an char. Now, by saying
*(x + j) = <some value>
you're trying to assign a value to the char that x (or, rather x + j, in general) points to. Fine, but wait, wait, what does x (or, x + j) actually point to at present?
Answer: x itself is not initialized explicitly, so it does not point to any valid memory where you can write the value. Standards specify, trying to read from or write to an uninitlalized memory location invokes undefined behaviour. Segmentation fault is one of the side effects of UB.
To avoid, you need to allocate memory to x first (so that it points to a valid memory location) and then put the value to the memory location it points to. You can use malloc() and family of functions to get the memory allocation done.

Variable being used without being initialized? C Language

I can't quite figure out what my issue is here. I keep getting an error in my code.
Error: Run-Time Check Failure: Variable used without being initialized.
: warning C4700: uninitialized local variable 'b' used
can someone help me solve this problem ? Any help would be appreciated.I'm using visual studio as a compiler for C and I'm a beginner in it and this is a one of the assignment. I don't see why i keep getting this issue if i input "int b;" in the beginning of the program. Wouldn't that variable be initialized?
Here is the code:
#include <stdio.h>
//Create a program that asks the user to enter a number until the user enters a -1 to stop
int main()
{
int b;
//as long as the number is not -1, print the number on the screen
while(b!=-1) {
printf("Hello there! would you please enter a number?");
scanf(" %d",&b);
//as long as the number is not -1, print the number on the screen
if(b!=-1){
printf("Thank you for your time and consideration but the following %d you entered wasn't quite what we expected. Can you please enter another?\n",b);
//When the user enters a -1 print the message “Have a Nice Day :)” and end the program
}else {
printf("Have a Nice Day :), and see you soon\n");
}
}
return 0;
}
When you declare a variable, such as you have:
int b;
It is not initialised to have any value, it's value is unknown until you initialise it.
To fix this error, replace
int b;
With
int b = 0;
Error is here:
int main()
{
int b;
//as long as the number is not -1, print the number on the screen
while(b!=-1) {
Since you haven't initialized b, it can be anything. You then use it as a condition for while loop. This is very dangerous.
It may be that system randomly assign value of -1 ( its a rare possibility ) to it .. in that case your while loop will not be actioned
Intialize b to some value
For eg do this:
int b = 0;
You're doing:
int b;
and then doing:
while(b!=-1) {
without ever initializing b. The problem is exactly what your warning is telling you it is.
C does not automatically initialize local variables for you, the programmer has to take care of that. int b allocates memory for your variable, but doesn't put a value in there, and it will contain whatever garbage value was in that memory prior to allocation. Your variable won't be initialized until you explicit assign, or another function explicitly assigns, a value to it.
int b;
is a variable declaration. Explicitly, the value is not initialized. The compiler will emit instructions for the program to reserve space to store an integer at a later time.
int b = 1;
this is a variable declaration with initialization.
int b;
while (b != -1)
this is use of an uninitialized variable, but so is
int a = rand() % 3; // so 'a' can be 0, 1 and or 2.
int b;
if (a == 0)
b = 1;
else if (a == 1)
b = 2;
printf("b = %d\n", b);
this is also a potential cause of uninitialized use of b. If 'a' is 2, we never assign a default value to b.
Upshot is you should always try to specify the default value with the declaration. If the logic that will determine initialization is complex, consider using an out-of-bounds value, as you are using -1.
Can you spot the bug in the following?
int b = -1;
if (a == 0)
b = 1;
else if (a == 1)
b = 2;
else if (a > 2)
b = 3;
if (b == -1) {
// this is an error, handle it.
}

Several basic C questions

I am a person who is trying to learn C, but I got stuck at a few points while doing my projects:
1) How exactly can I implement random integer generation? I have Googled and found the code for 0 to x generation with the code below, yet how about between 2 integers that I decide (like between X and Y)?
int random;
random = random(100);
2) How can I set a variable to NULL in the beginning (like in Java) and manipulate it if it is NULL? For instance I want to achieve the following:
int a = null;
if (a == null){
a = 3;
}
1)
int r = random(Y - X) + X;
2)
Integers can't be null in either C or Java. In C only pointers can be null, represented by pointing them to zero. However, I suggest you don't get into the whole pointer mess before getting the basics down.
1- How exactly can I implement a random integer generation [...]
See FAQ 13.15 and FAQ 13.16 -- the latter explicitly answers this question.
2- How can I set a variable null in the begining
For floats and integral types you assign them to the magic value 0. For pointers you can assign them to 0 (again) or the macro NULL.
To get the range you want (y-x) multiply each random numberby (y-x). To make them start at x and end at y add x to each number (already multiplied by (y-z)). Assume that y > x.
int i;
for (i = 0; i < NrOfNumers; i++)
{
randomNumberSequence[i] = randomNumberSequence[i]*(y-x) + x;
}
In C you often see the following:
int x = -1;
if (x == -1) { x = 3; } else { /* do nothing */ }
This assumes that the value type is actually unsigned or at least that -1 is not a valid value. You also can do:
#define UNINITIALIZED ((int8_t) -128) /* -128 has no inverse with 8-bit */
...
int8_t x = UNINITIALIZED;
if (x == UNINITIALIZED) { x = 3; } else { /* do nothing */ }

Resources