#include <stdio.h>
#include <stdlib.h>
int factor(int n, int k, int v[], int *check){
int i=0;
if (n==1) {
*check=1;
return 1;
}
while (i<k && *check!=1){
if (n%v[i]==0) factor(n/v[i], k, v, check);
i++;
}
if (*check==1) return 1;
else return 0;
}
int fac(int n, int k, int v[]){
int check;
return factor(n,k,v,&check);
}
int main(){
int i,k, temp;
int P[2]={2,3};
int A[100];
for (i=1; i<20;i++) A[i]=0;
for (i=1; i<20;i++) {
temp=fac(i,2,P);
if(temp==1) {/*printf("%d ", temp);*/ A[i]=6; }
}
printf("\n");
for (i=1; i<20;i++) printf("%d ", A[i]);
return 1;
}
This function finds the integers <20 that can be expressed as the product of 2 and 3. Factor and fac check if the number can be expressed in that way; in the main i create a vector A in this way: A[i]=0 if i cannot be expressed in that way, A[i]=6 otherwise. The problem is that if i use the commented line the program works right, but if i don't use it, A will be made of only 6s. How is that possible (i think it's corrleated with the pointer argument in factor function, but i'm not sure)?
Problems like this usually mean that there is undefined behaviour somewhere. In order to spot the problem early, always compile with warnings enabled; e.g. if you use GCC, always provide at least -Wall flag (and -O3 often helps to get more warnings, since compiler analyzes the code more thoroughly).
E.g. this is the output when I compile your code:
gcc -Wall -O3 my.c
my.c: In function ‘fac’:
my.c:19:7: warning: ‘check’ may be used uninitialized in this function [-Wmaybe-uninitialized]
int check;
^
So, as it points out, the variable check is left uninitialized. I'm afraid that your intention was to always initialize it with this snippet:
if (n==1) {
*check=1;
return 1;
}
But it doesn't work this way: the next time fac is called, there is a new local variable check, and it's left uninitialized.
I'm not sure the logic in your code is correct, but fixing this undefined behaviour should eliminate the "strange" error which you observe.
Related
Wrote a program that multiply two arrays like this:
uv = u1v1 + u2v2 + u3v3 + ... un*vn
after getting from the user both of the arrays, i get a "signal: segmentation fault (core dumped)" error.
here's the code:
#include <stdio.h>
int scalar_product(int vectorU[], int vectorV[], int vectorLength) {
int i, sum = 0;
for (i = 0; i < vectorLength; i++)
sum += (vectorU[i] * vectorV[i]);
return sum;
}
void userInterface() {
int vectorLength = 0, i;
printf("Please enter the length of the vectors: ");
scanf("%d", &vectorLength);
int vectorU[vectorLength], vectorV[vectorLength];
printf("\nVector U:");
for (i = 0; i < vectorLength; i++) {
printf("\n%d) ", (i + 1));
scanf("%d", &vectorU[i]);
}
printf("\nVector V:");
for (i = 0; i < vectorLength; i++) {
printf("\n%d) ", (i + 1));
scanf("%d", &vectorV[i]);
}
printf(scalar_product(vectorU, vectorV, vectorLength));
}
main(void) {
userInterface();
}
This call of printf is incorrect
printf(scalar_product(vectorU, vectorV, vectorLength));
You need to write at least
printf( "%d\n", scalar_product(vectorU, vectorV, vectorLength));
Also it would be better to declare and define the function like
long long int scalar_product( const int vectorU[], const int vectorV[], int vectorLength) {
long long int sum = 0;
for ( int i = 0; i < vectorLength; i++)
sum += ( long long int )vectorU[i] * vectorV[i];
return sum;
}
To output the result you need to use the format string "%lld\n"..
The type long long int is used to avoid an overflow.
Another way is to declare the function return type as double.
Also you forgot to specify the return type int of the function main.
Here:
printf(scalar_product(vectorU, vectorV, vectorLength));
... you have failed to specify a format for printf. As a result, it attempts to interpret the result of scalar_product() as a pointer to the format string. Undefined behavior results.
If your compiler is not emitting a warning about that then you should either learn how to turn up the warning level so that it does, or else get a better compiler. If your compiler is emitting a warning about it, then take this as a lesson that it is not safe to ignore compiler warnings.
Probably you wanted somethign more like this:
printf("%d\n", scalar_product(vectorU, vectorV, vectorLength));
As a minor additional issue, you have forgotten the return type for main(). Your compiler is probably treating it as returning int, which turns out to be the right thing to do, but that doesn't make your code correct. You want:
int main(void) {
// ...
With those two changes, your program compiles for me without any diagnostics, and runs without error, producing the result I expect.
At least, for small vector lengths. If you try really large vectors then you might exceed the available space for allocating your vectors on the stack.
I am writing a C program to sum up prime numbers below a certain limit (9 for now). I expect 17 but the compiler gave me an unexpected output of 32781.
#include <stdio.h>
#include <stdbool.h>
bool isprime(int n);
int main(){
const int LIMIT=9;
int sum;
for (int j=1;j<LIMIT;j++){
if (isprime(j)){
sum+=j;
}
}
printf("%d",sum);
return 0;
}
bool isprime(int n){
if (n<=1){
return false;
}
else{
for(int i=2;i<n;i++){
if (n%i==0){
return false;
break;
}
}
return true;
}
}
Does anyone understand why this happened?
You declarred int sum; but didn't give sum a starting value, so it's basically reading garbage from memory. In c you need to initialize your variables properly. int sum = 0; should fix the problem.
If you are using clang as your compiler, compiling using -Wall should warn you about this.
Local variables are not initialized, so you need to initialize at declaration or before use.
int sum = 0;
or...
int sum;
for (sum = 0; bla; bla)
If the variable had been declared globally (outside of any function... main is a function) it will automatically initialize to 0.
#include <stdio.h>
int a;
int main(void)
{
int b;
printf("%d\n%d\n", a, b);
return 0;
}
Variable 'a' will be 0 and 'b' will be garbage because it's an uninitialized local variable.
#include <stdio.h>
main()
{
int n;
n+=2;
printf("sum=%d", n);
return 0;
}
Here the 'Sum'=2
Another program:-
#include <stdio.h>
main()
{
int n,a=2;
n+=a;
printf("sum=%d", n);
return 0;
}
here the output 'sum' = 3
WHY so?? What is the problem in the code??
This is Undefined Behavior. Using uninitialized variables (n in both snippets) can produce unexpected results, meaning that running the first code twice might produce different outputs. There is no "correct" output for either of the codes, but if you'll set n to a specific value in both codes, you'll start getting consistent results.
This is UB (Undefined Behavior):
main()
{
int n;
printf("sum=%d", n);
return 0;
}
This is not:
main()
{
int n = 0;
printf("sum=%d", n);
return 0;
}
When you don't assign a value to a local variable in C, its value is undefined. So in some cases it will be 0, in some 1, in some, something else entirely. You cannot know what it will be and you should never rely on it. Instead, initialize your local variables:
int n = 0; // initialization
n += 2;
printf("sum=%d", n); // will always print 2
I have recently started coding in C, and am doing some stuff on project Euler. This is my code for challenge three so far. The only problem is when I run the compiled code it throws a segmentation fault. I think it may be due to a pointer I called, the suspect pointer is underneath my comment. I did some research into the subject but I cant seem to be able to fix the error. Any advice?
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
bool is_prime(int k);
int * factors(int num);
int main(){
int input;
while (true){
printf("Enter a number to get the prime factorization of: ");
scanf("%d", &input);
if (is_prime(input) == true){
printf("That number is already prime!");
}else{
break;
}
}
//This is the pointer I think is causing the problem
int * var = factors(input);
int k;
for (k = 0; k < 12; k++){
printf("%d", var[k]);
}
}
bool is_prime(int k){
int i;
double half = ceil(k / 2);
for (i = 2; i <= half; i++){
if (((int)(k) % i) == 0){
return false;
break;
}
}
return true;
}
int * factors(int num){
int xi;
static int array[1000];
int increment = 0;
for (xi = 1;xi < ceil(num / 2); xi++){
if (num % xi == 0){
array[increment] = xi;
increment++;
}
}
}
The factors function has no return statement. It's supposed to return a pointer but it doesn't return anything.
Side note: Enable your compiler's warnings (e.g., with gcc -Wall -Wextra). If they're already enabled don't ignore them!
Your function is declared as
int * factors(int num);
but it's definition doesn't return anything and yet you are using it's return value in assignment. This triggers undefined behavior. It will compile if compiled without rigorous warnings and the return value will most likely be whatever random value happened to be left in the return register (e.g. EAX on x86).
C-99 Standard § 6.9.1/12 Function definitions
If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.
#include<stdio.h>
#include<conio.h>
//#include<alloc.h>
int* mergeSort(int*,int);
int* merge(int*,int*,int);
void main()
{
int n;int i=0;
int *a,*b;
scanf("%d",&n);
a=(int)malloc(n*sizeof(int));
for(;i<n;i++)
scanf("%d",&a[i]);
b=mergeSort(a,n);
for(i=0;i<n;i++)
printf("%d ",b[i]);
}
int* mergeSort(int *b,int n)
{
int temp,*s;
if(n>2)
{
mergeSort(b,n/2);
mergeSort(b+n/2,n-n/2);
s=merge(b,b+n/2,n);
return s;
}
else if(n==2)
{
if(b[0]>b[1])
{
temp=b[0];
b[0]=b[1];
b[1]=temp;
}
return;
}
}
int* merge(int* a,int* c,int n)
{
int i=0,j=0,k=0,
int* x;
while( (j ! =n/2) && (k != (n-n/2)) && (i < n))
{
if(a[j]<c[k])
{
x[i]=a[j];
j++;
i++;
}
else
{
x[i]=c[k];
k++;
i++;
}
}
for( ; j<n/2; j++,i++)
x[i]=a[j];
for( ; k < (n-n/2); k++,i++)
x[i]=c[k];
return x;
}
when i run this code,it hangs after inputting all the elements of the array in first for loop. Please help me, how can i correct it to make it work successfully? it hangs on calling the mergeSort function from main() function.
it hangs after inputting all the elements of the array in first for loop.
hangs? Are you sure... that's pretty good considering your merge code declares a pointer to an int:
int *x;
and never initializes it, then tries to jump to an offset (i) past it:
x[i]=a[j];
Change your code to this:
int *x = malloc(n * sizeof(int));
and it should stop crashing/hanging whatever.
FYI, whenever you malloc() you should free() right now you have memory leaks.
There are some things wrong, not only basic things like void main instead of int main but also eg the return; in mergeSort() which should return int* and the uninitialized x. Also one important thing about the algorithm: You seem to assume that n is a power of 2: you recursively divide by 2 and assume that it always is an untruncated integer.
For starters, the code doesn't compile in a C++ compiler (I know it's C code, but still...),
a couple of problems are:
line 11:
a=(int)malloc(n*sizeof(int));
why are you casting a pointer to an int? a is an int *
line 38:
return;
you are returning from mergeSort without a return value...that can't be good
I recommend that you fix all the compiler errors and warnings, then try again