C language cygwin compiler, not sure why this is happening - c

My job is to prove fermats theory incorrect using c. so what i did was have nested loops, its pretty easy to read.
here is the code:
#include <stdio.h>
#include <math.h>
quadtest(unsigned long long int a, unsigned long long int b, unsigned long long int c, unsigned int n)
{
if ((pow(a,n)+pow(b,n))==pow(c,n))
return 1;
else
return 0;
}
main()
{
unsigned long long int a;
unsigned long long int b;
unsigned long long int c;
unsigned int n;
//a=1; b=1; c=1; n=1;
for(n=2; n<100; n++)
{
printf("\nn=%d",n);
for(c=1; c<500; c++)
{
printf("\ntrying now c=%d and n=%d",c,n);
for(b=1; b<500; b++)
{
if (quadtest(a,b,c,n)) break;
//printf("\nb=%d, n=%d",b,n);
}
for(a=1; a<500; a++)
{
if (quadtest(a,b,c,n)) break;
//printf("\na=%d, n=%d",a,n);
}
}
printf("\nthe right values to prove fermats theory wrong are n=%d,c=%d,b=%d,a=%d",n,c,b,a);
}
}
after being compiled, im getting "trying c=random number, n=0. n always equals 0 for some reason even though its never supposed to be 0.
im also getting something like "the right values to prove fermats theory wrong are n=99,c=500,b=0,a=500"
which once again, neither a, b, c, or n are supposed to be 0. not sure what the problem is

There are two clear problems with your code:
You define several variables, and each is initialised except for a. You call a function using a uninitialised. This is undefined behaviour and could explain your problem.
Secondly, you are using the incorrect specifier in printf. %d is used for int; %llu is for unsigned long long. Using the wrong specifier can lead to incorrect values being output.

Related

Surprising segfault in C code

I cannot understand how this code is causing a segfault when I run it, can anyone help me understand what is going on??
#include <stdio.h>
unsigned long long factorial(unsigned long long x, unsigned long long amt)
{
if (x == 1ULL) return amt;
else return factorial(x-1ULL, amt*x);
}
int main(int argc, char *argv[])
{
for (unsigned long long i = 0; i < 10ULL ;i++) {
printf("%llu\n", factorial(i, 1ULL));
}
}
First, the segfaults are not necessarily caused be invalid pointer dereference. In this case, it is actually caused by infinite recursion and eventual running out of stack space. Why? The essential requirement of a recursion function is it has to finish and terminate the recursion at some state, if you look carefully your code, in function factorial, if x is 0, then the recursion will become endless and eventually crash your program. You can fix this by change the terminate condition to:
if (x <= 1ULL) return amt;
In the orginal code :
if (x == 1ULL) return amt;
is meant to be the exit condition for this recursive function factorial. However when a value of zero is passed to the function and given that the type of x is unsigned long long, first recursive call to the function factorial with the parameter x-1ULL would set the value of x to very large value (18446744073709551615 is what I got here). Successive recursive calls to factorial will gradually deplete the stack space allocated for the program to the point where you get a segmentation fault.
You should have been doing this:
#include <stdio.h>
unsigned long long factorial(unsigned long long x, unsigned long long amt)
{
if (x == 0ULL) // Changed the exit condition, see Reference [1]
return amt; // Bear in mind that the initial value for amt you passed is 1
amt*=x; // See Reference [2]
return factorial(x-1ULL, amt);
}
int main(int argc, char *argv[]) {
for (unsigned long long i = 0; i < 10ULL ;i++) {
printf("%llu\n", factorial(i, 1ULL));
}
}
References
The idea of the factorial (in simple terms) is used to compute the number of permutations (combinations) of arranging a set of n numbers. It can be said that an empty set can only be ordered one way, so 0! = 1. Check this.
I feel this is more readable than factorial(x-1ULL, amt*x)
Note
The ULL suffixes are redundant here and may be removed altogether.

Runtime error in my code

I was trying to implement this problem from SPOJ: http://www.spoj.com/problems/COINS/ using memoization but I keep getting Runtime error and cant figure out why. Here is my code:
#include<stdio.h>
long long int max(long long int a,long long int b)
{
if(a >= b)
return a;
else
return b;
}
long long int dp[100000];
long long solve(long long int n)
{
long long ans;
if(n<=50000)
return dp[n];
else
ans=(n,solve(n/2)+solve(n/3)+solve(n/4));
return ans;
}
int main()
{
long long int n;
int t;
for(int i = 0;i <=50000;i++)
{
dp[i] = max(i,dp[i/2] + dp[i/3] + dp[i/4]);
}
while((scanf("%d",&t))>0)
printf("%lld",solve(n));
return 0;
}
Here are a few problems:
In solve, you have ans = (n,solve(n/2)...); The leading n has no effect. Did you intend this to be an argument list to max? If so, you need to add max. Otherwise it's just a comma expression and you might as well remove the leading n.
In main, your initialization of dp has a problem. Consider the first pass through the loop, when i is 0. In this case, i/2 etc. will also be zero, hence those dp values will be undefined. Try setting dp[0] explicitly, outside of the loop, and then start your loop at index 1 instead.
When printing the solution in main, you probably want to add newling \n to the end of your printf format string.
As noted by others, when calling solve from main, you are passing n rather than t.
The problem is most likely due to this:
while((scanf("%d",&t))>0)
printf("%lld",solve(n));
You are reading t but passing n which is uninitialized. You probably want to pass t to solve():
while((scanf("%d",&t))>0)
printf("%lld",solve(t));
Reason you get Runtime Error
while((scanf("%d",&t))>0)
printf("%lld",solve(n));
Here, You get input in variable t but pass variable n to solve function. Use variable t or n for both case. It will solve your problem.

c variable turning into -17918 when incremented

hi i am making a programming language that will run on the nintendo gameboy in c
which is why you will see some functions like waitpad();
but this question is unrelated the the gameboy librarys
for some reason when ever i try to increment a certain variable in my main.c file:
#include <stdio.h>
#include <gb/gb.h>
#include "convert.h"
#include "display.h"
#include "input.h"
#include "functions.h"
#include "interpreter.h"
unsigned char cnt[5] = {1,2,3,4,5};//cnt is short for counters
unsigned char k = 0;
unsigned char running = 1;
unsigned char memory[2048];
unsigned char code[2048];
int main()
{
Clear_mem();
Clear_code();
while(running == 1) {
display(cnt[0],cnt[1],cnt[2],cnt[3],cnt[4]);
printf("cnt[0] = %d\n", cnt[0]);
cnt[0]++;//turns into -17918
printf("Press Start To Enter Next Character\n");
waitpad(J_START);
code[k] = input();
interpret(code[k]);
k++;
}
return 0;
}
cnt[0] turns into -17918
can anyone see any problem that would cause it to behave this way?
You ask if anyone sees a problem, well - yes, here is a problem:
unsigned char k = 0;
unsigned char running = 1;
unsigned char code[2048];
while(running == 1) {
code[k] = input();
k++;
}
If k >= 2048, then code[k] = ... will cause a memory-override.
After a memory-override, pretty much anything can happens (undefined behavior).
Having said that, the value of k can be larger than 2047 only if CHAR_BIT is larger than 11.
Add #include <limits.h> to your program and make sure that CHAR_BIT is not larger than 11.
You have to convert it to an integer, because that's what you're trying to print:
printf("cnt[0] = %d\n", (int) cnt[0]);
When you're using a variadic function like printf, you have to make sure you're passing the right type. Check your compiler warning settings, new compilers can easily detect these kind of problems.
if you want to print the character value of your character variable you should print it like this:
printf("cnt[0] = %c\n", cnt[0]);
If you print it using %d the expansion of the character to a size of int could be negative for characters over half a character's size (0x80 and up).
If you insist on printing it as an int cast the variable like this:
printf("cnt[0] = %d\n", (int)cnt[0]);

Scanf error in C

So i have the following C code:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int L,R;
scanf("%d",&L);
scanf("%d",&R);
long long int *a=malloc(L*sizeof(long long int*));
long long int *A=malloc(L*sizeof(long long int*));
int i;
for(i=0;i<L;i++)
scanf("%lld %lld",&a[i],&A[i]);
for(i=0;i<L;i++)
{
printf("a(%d)==%lld and A(%d)==%lld\n",i,a[i],i,A[i]);
}
return 0;
}
which is unfortunately only a starter of my problem, and with the print loop on the end i want to determine if the input values are assigned correctly into the arrays a and A
( the R value has to do with another two arrays b and B but for now this doesn't matter).
when i compile and run the program with these inputs:
3 5
10 1 3 2 10 1
i get on the output:
a(0)==10 and A(0)==10
a(1)==3 and A(1)==2
a(2)==10 and A(2)==1
Notice that everything puts up correctly, but the value A(0)=10 which instead of calculated to 1 , scanf reads for a second time the value 10, skips the value 1 and proceeds reading the rest of the values correctly. I'm really stuck. Does anyone have an idea why this incident occurs?
there is a mistake in the following line:
long long int *a=malloc(L*sizeof(long long int*));
you need to use sizeof(long long int) and not sizeof(long long int*)
Hope this helps to mitigate your issues.
Actually, the best way to do it is like this:
long long int *a = malloc(L * sizeof(*a));
That way if you change the type you only have to change it in one place.

C return value is displaying some bizarre behavior

A fair warning — I'm very new to C, and there's some unpredictable behavior. I'm not sure how to begin troubleshooting this.
I'm trying to solve one of the early Euler problems (to do with numerical palindromes) and I'm having trouble with my check function. When a number a is passed through rev(a), everything works as it should. When passed through ret(a) (a function which will eventually check for equality, bool type, etc), it returns totally wrong number — something to do with memory, I think. Can anybody help me, please?
#include <stdio.h>
#include <stdbool.h>
int rev(int a);
int check(int a);
main() {
int a = 12;
printf("%i ", a);
printf("%i ", rev(a));
printf("%i\n", ret(a));
}
int ret(int a){
return rev(a);
}
int rev(int a){
int b;
while (a>0){
b = (b*10) + a%10;
a/=10;
}
return b;
}
In rev, the first iteration of the loop
int b;
while (a>0){
b = (b*10) + a%10;
operates on an uninitialised value of b. This makes the end result unpredictable and almost certainly wrong.
The fix is pretty simple - you just need to initialise b to 0
int rev(int a){
int b = 0;
// function unchanged beyond this
If calls to rev worked for you, this was just luck (either good or bad, depending how you look at it). Reading the content of uninitialised memory can have any effect, including the stack for b just happening to be set to 0. You'd probably have found that changing platform or compiler flags caused things to break.

Resources