Why this program stops unexpectedly in the middle of the input - c

i have written this code for a question on codechef (A4)....when i give the input:
2
4 2
This program stops unexpectedly without taking further input ....can some please point out the mistake in the code?
#include <stdio.h>
#include<math.h>
void number(long int a,int b)
{
int c;
c=b;
int first[c],last[c],e=1,i;
long int d;
d=pow(a,a);
for(i=(c-1);i>=0;i--)
{
last[i]=fmod(d,pow(10,e));
e++;
}
e=1;
while(d>pow(10,(b-1)))
d/=10;
for(i=(c-1);i>=0;i--)
{
first[i]=fmod(d,pow(10,e));
e++;
}
for(i=0;i<c;i++)
printf("%d",first[i]);
printf(" ");
for(i=0;i<c;i++)
printf("%d",last[i]);
printf("\n");
}
int main()
{ int T;
scanf("%d",&T);
while(T--)
{ long int a;
int b;
scanf("%ld %d",a,b);
number(a,b);
}
return 0;
}

scanf("%ld %d",&a,&b);
Using uninitialized variables lead to UB. You should use &a and &b to scan variables

In your code you have
scanf("&ld %d",a,b);
It means you're trying to input integers to the memory locations of values of a and b. For and example let value of a = 1234566466 (long int), and b = 1234 (int). Accordingly 1234 is a memory location which is at the start of the RAM. Tn that area System files are loaded. So you are going to change system behaviour. That is not allowed.
Further when the complier allocate some memory space to your program, you can access only the memory which is inside your memory segment directly. But above statement trying to access another segment.
That's why you get segmentatin fault.

You are passing an integer to a function that expects a pointer, for scanf the "%d" and "%ld" specifiers expect int * and long int * respectively, and you pass int and long int, so when trying to access the integers as if they were memory addresses the segmentation fault occurs.
The correct way to call scanf would be as Gopi said
scanf("%ld %d", &a, &b);
there you pass a and b addresses instead of their values.

Related

Why am i getting EXC_BAD_ACCESS (code=1, address=0x0)?

I am trying to write a program that, when given a certain price, will break it into 20s, 10s, 5s and 1s.
However, I am getting the following error: EXC_BAD_ACCESS (code=1, address=0x0)
The error shows up on the line: *tens=diff in the function.
I do not understand what is wrong!
Here is the code:
#include<stdio.h>
#include<stdlib.h>
void pay_month(int , int *, int *, int *, int *);
int main(){
int dollars, *twenties=0, *tens=0, *fives=0, *ones=0;
printf("enter amount to pay: ");
scanf("%d",&dollars);
pay_month(dollars, twenties, tens, fives, ones);
return 0;
}
void pay_month(int dollars, int *twenties, int *tens, int *fives, int
*ones){
int diff=0;
int odolls;
odolls=dollars;
while(dollars%20!=0){
dollars=dollars-1;
diff++;
}
*tens=diff;
*twenties=dollars/20;
diff=0;
while(*tens%10!=0){
*tens=*tens-1;
diff++;
}
*tens=*tens/10;
*fives=diff;
diff=0;
while(*fives%5!=0){
*fives=*fives-1;
diff++;
}
*ones=diff;
diff=0;
while(*ones%1!=0){
*ones=*ones-1;
diff++;
}
printf("in %d there is %d twentis %d tens %d fives and %d ones\n",odolls, *twenties, *tens, *fives, *ones);
}
You are dereferencing a NULL pointer. That is, you are asking the computer to write into memory location 0. You are not allowed to do that.
I think what you've done is used pointers without quite understanding how to obtain them. Possibly just to stop the compiler from throwing errors.
This simple change should solve the problem:
int dollars, twenties=0, tens=0, fives=0, ones=0;
printf("enter amount to pay: ");
scanf("%d",&dollars);
pay_month(dollars, &twenties, &tens, &fives, &ones);
Notice that none of the values in the calling function are pointers anymore. They're just integers. You prefix with & when passing them to pay_month. That's the reference operator, which obtains a pointer to where the value is stored.
Now, when you dereference the tens pointer inside pay_month, you're actually accessing the same part of memory where the value tens is stored on the stack in main.
a classic case of pointers and variables
essentially when you are declaring pointer as
int *twenties=0, *tens=0, *fives=0, *ones=0;
you are essentially making these pointers to point to NULL memory which means no memory is allocated to those.
one way to solve this is by declaring these as variables and passing the address of these variables
int dollars, twenties=0, tens=0, fives=0, ones=0;
and
pay_month(dollars, &twenties, &tens, &fives, &ones);

Call by value in C

I'm new to programming and I am currently working on C.
I learned that C does not have call by reference. The programs that we write to pass the address of actual parameters to the formal parameters is also call by Value in C.
Correct me if I'm wrong.. However, I ran this program :
//Swapping of two numbers using functions.
#include
void swap(int *,int *);
void main()
{
int x,y;
printf ("Enter the values of x and y : ");
scanf("%d %d",&x,&y);
swap(x,y);
printf("The value of x = %d and y = %d",x,y);
}
void swap(int *a,int *b)
{
int temp;
temp=*b;
*b=*a;
*a=temp;
}
It compiles just fine.. however, I'm getting a Segmentation Fault in the Output.
It asks me the enter the value of X and Y and then gives, Segmentation fault..
Please help!!
you are sending an int to a function that expects int*, thus when you are dereferencing - temp=*b; you are trying to access memory you don't own -> segfault. Call swap like this: swap(&x,&y);
So close
swap(&x,&y);
You were not passing references (pointers)
To avoid similar segfaults at runtime, always compile with -Wall.
Actually, there is a way to pass-by-reference in C, just change two lines in your code like this:
#define swap(x,y) swap_impl__(&(x), &(y))
static void swap_impl__(int *a, int *b)
{
int temp;
temp=*b;
*b=*a;
*a=temp;
}
void main()
{
int x,y;
printf ("Enter the values of x and y : ");
scanf("%d %d",&x,&y);
swap(x,y);
printf("The value of x = %d and y = %d",x,y);
}
the call by value method of passing arguments to a function copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument.
but here you are passing values
swap(x,y)
but taking it as address
void swap(int *a,int *b)
so it is looking for an address which passed by your variable.
for example, if you have passed something like
swap(x,y)
and
if we have x=100 and y=200, then it is assuming 100 and 200 to be addresses
and trying to access it will definitely give you error as they may not exist or having garbage value.

Pointers in C for a rookie

I am just starting to learn programming for a unit I am doing in my engineering course and I have come across pointers. I just wanted some reassurance that I actually understand the concept correctly in terms of using a pointer as an argument in a function. If I understand it correctly, you pass a pointer to an address of a variable you would like to be altered by a separate function called, even though it is a local variable within the scope of the calling function. Does that make sense? I have an example from my text book which I re-wrote. The only thing is they gave it in two incomplete parts and I put it together, filled in the blanks and added the final printf statement in the main function. I'll paste it here:
#include <stdio.h>
#include <stdlib.h>
#define READ_OK 0
#define READ_ERROR 1
int read_num(int lo, int hi, int *num);
int main(int argc, char *argv[])
{
int lo = 0, hi = 0, *num, val;
printf("Please enter a lower bound and an upper bound for your range,respectively\nLower: ");
scanf("%d", &lo);
printf("Upper: ");
scanf("%d", &hi);
num = &val;
if(read_num(lo,hi, &val) != READ_OK)
{
printf("Read error, program abort\n");
exit(EXIT_FAILURE);
}
else
{
printf("You entered %d, press any key to continue: \n", val);
getchar();
}
return 0;
}
int read_num(int lo, int hi, int *num)
{
int next;
printf("Enter a number between %d and %d: ", lo, hi);
while(scanf("%d", &next)==1)
{
if (lo<=next && next<=hi)
{
*num = next;
return READ_OK;
}
printf("%d is not between %d and %d\nTry again: ", next, lo, hi);
}
return READ_ERROR;
}
So is my understanding correct? "val" gets modified in read_num() by passing it's address in the form of pointer "*num", in which the the value for "next" is then written?
PS: is this syntax correct?
PPS: What would this process specifically be called?
Thanks a bunch for any help :)
The *num is not necessary inside the main() function. As you are passing the address of the val inside the read_num() , so any changes from the read_num() will also affect the value inside main() as you are working with the address.
In your program you have basically use two different pointers- one is inside main which is num, and another inside read_num() which is also num, for more understanding see the scope of a variable in c. As the val is inside main so you don't need to use pointer here, because you have the access of changing the value from the main as it is local to it. You will need pointer when you will be changing the value of val outside from the main, or from outside of the scope of the variable.

diffculty in entering strings in C using pointer

The following program works in gcc but on giving the value of T = 6, this program continues and does not end on asking for input strings. Any help guys if you recognise whats wrong with this program?
int main()
{ int T,i,j;
char *strings[T];
printf("Enter the Number of Strings to Reverse : \n");
scanf("%d ",&T);
for(i=0;i<T;i++)
{ strings[i] = (char *)malloc(100*sizeof(char));
scanf("%s\n",strings[i]);
}
for(i=0;i<T;i++)
{printf(" The String %d is : %s\n",i+1,strings[i]);
}
return 0;
}
T is not initialised (Remember in C++, local scope variables are not automatically initialised) :
int T= 6;
T is not initialized inside main() therefore has an undefined value.
char *strings[T] creates an array of char * pointers of an undefined length.
Fix this using:
int T=6;
Or, given T is in fact constant:
const int T=6
or perhaps better
#define T 6
Feel free to use a more mnemonic name than T.

Declaring arrays in c language without initial size

Write a program to manipulate the temperature details as given below.
- Input the number of days to be calculated. – Main function
- Input temperature in Celsius – input function
- Convert the temperature from Celsius to Fahrenheit.- Separate function
- find the average temperature in Fahrenheit.
how can I make this program without initial size of array ??
#include<stdio.h>
#include<conio.h>
void input(int);
int temp[10];
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
void input(int d)
{
int x=0;
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
void conv()
{
int x=0;
for(x=0;x<d;x++)
{
temp[x]=1.8*temp[x]+32;
}
}
In C arrays and pointers are closely related. In fact, by design an array is just a syntax convention for accessing a pointer to an allocated memory. *(see note for more details below)
So in C the statement
anyarray[n]
is the same as
*(anyarray+n)
Using pointer arithmetic.
You don't really have to worry about the details to make it "work" as it is designed to be somewhat intuitive.
Just create a pointer, and allocate the memory and then access it like as an array.
Here is some examples --
int *temp = null; // this will be our array
// allocate space for 10 items
temp = malloc(sizeof(int)*10);
// reference the first element of temp
temp[0] = 70;
// free the memory when done
free(temp);
Remember -- if you access outside of the allocated area you will have unknown effects.
To be clear it is the indexing operator ([ ]) that is translated to pointer arithmetic. This is not an array in the modern sense of the
type. Whether (or not) the pointer involved points to (dynamically) allocated
memory is inconsequential to how this operator works. In a more modern language you would be able to operate on the array as an abstract type (to see how big it is, for example), you can't do this in C.
An array without an initial size is basically just a pointer. In order to dynamically set the size of the array, you need to use the malloc() or calloc() functions. These will allocate a specified amount of bytes of memory.
In your code above, declare temp as an int pointer
int *temp;
Then allocate space for it using malloc() or calloc(). The argument that these functions take is is the number of bytes of memory to allocate. In this case, you want enough space for d ints. So...
temp = malloc(d * sizeof(int));
malloc returns a pointer to the first byte in the block of memory that was just allocated. Regular arrays are simply pointers to the first byte in a sectioned off block of memory, which is exactly what temp is now. Thus, you can treat the temp pointer as an array! Like so:
temp[1] = 10;
int foo = temp[1];
printf("%d", foo);
Outputs
10
You will need to declare temp as an int pointer (instead of an int array). Then, you can use malloc in your main (after your first scanf):
temp = malloc(d * sizeof(int));
If your compiler supports c99, then simply use VLA(variable length array).Use like this:
void input(int);
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
int temp[d];
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
Now temp[] is defined inside main() after date input.
1-add #include<stdlib.h> at the top of your file. Then modify the conv() code as follows:
2- modify temp declaration as follows (global variable):
int *temp;
3- modify input(int d) function as follows (tested on Visual Studio 2010):
void input(int d)
{
int x=0;
temp=(int*)malloc(sizeof(int)*d);
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
Allocate the "array" dynamically on the heap after you read the size.
I didn't change anything else so you may see it clearly.
#include<stdio.h>
#include<conio.h>
#include <stdlib.h> //here
void input(int);
int *temp=0; //here
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
temp=malloc(d * sizeof(int)); //here
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
void input(int d)
{
int x=0;
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
void conv()
{
int x=0;
for(x=0;x<d;x++)
{
temp[x]=1.8*temp[x]+32;
}
}
Maybe it's late to answer but...
If you work with small embedded system you might not have malloc and free functions.
So you have to sacrifice memory for 366 * sizeof(your_type), define it statically and use as a circular buffer. Then you can always slice it by number of days you need to calculate an average value.
Of course this makes natural constrains. You can define it by yourself.

Resources