Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So, as an exercise, I am developing a code that uses a recursive function in order to make a simple mathematical expressions calculator. The problem is, I am getting a segmentation fault (6) or (11) when I run it, but I have checked a hundred times and each function call seems to be accessing memory only from the variables in the function just above it on the stack, provided by the pointer *init. Where am I getting this wrong?
Code is as follows:
int solve(char *expression, int *init) {
int result;
int l = strlen(expression);
int i = *init;
//Inicializing result:
for (int n = 0; n <= l; n++) {
if ((expression[n]=='1')||(expression[n]=='2')||(expression[n]=='3')||(expression[n]=='4')||(expression[n]=='5')||
(expression[n]=='6')||(expression[n]=='7')||(expression[n]=='8')||(expression[n]=='9')) {
result = expression[n]-48;
break;
}
}
//Doing calculations:
int j = i;
for (j; j <= l; j++) {
if (expression[j] == '(') {
result = result + solve(expression, &j);
}
if (expression[j] == '+')
result = result + (expression[j+1]-48);
if (expression[j] == '-')
result = result - (expression[j+1]-48);
if (expression[j] == '*')
result = result * (expression[j+1]-48);
if (expression[j] == '/')
result = result / (expression[j+1]-48);
if (expression[j] == ')')
return result;
}
return result;
}
There is infinite recursion in the code
int solve(char *expression, int *init) {
/* ... */
int j = i;
for (j; j <= l; j++) {
if (expression[j] == '(') {
result = result + solve(expression, &j);
/* ... */
If it ever founds a '(' in expression, then the function is called over and over again with the same parameters, until the program stack is filled up. Then you get a segfault.
When using loops or recursion, you should always make sure that the construct eventually terminates, i.e. it gets demonstrably closer to the terminating condition on every iteration. It's trivial to see when doing a simple loop like for(i=0;i<x;i++), but considerably harder when the iteration and the terminating conditions are scattered over a recursive function.
It's not the only problem with your code, but arguably the most severe one.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 3 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
This code is an exercise from a daily programming mailing list. I am trying to print out a list of given words in reverse order. The words are delimited by spaces. When running the code below, it enters into an infinite loop just printing the (new) first word. I have looked through the conditions and everything looks OK to me. I think it may take a fresh set of eyes to point out a simple mistake, but I can't find anything. Thanks to anyone who can lend a hand.
*Note: I am planning on adding back in the spaces to the output after this is figured out. I am aware the output will just be one long string without spaces so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void)
{
char *words;
words = "here world hello spam foo bar baz";
int space_indices[10];
int counter = 0;
// Find the spaces and keep track of the index numbers in the space_indices array
for (int i = 0; i < strlen(words); i++) {
if (words[i] == ' ') {
space_indices[counter] = i;
counter++;
}
}
for (int i = counter - 1; i >= 0; i--) {
if ( i = counter - 1) {
// Print the first word
for (int j = space_indices[i] + 1; j < strlen(words); j++) {
printf("%c", words[j]);
}
} else if (i >= 0) {
// Print the other words except for the last
for (int j = space_indices[i] + 1; j < space_indices[i + 1]; j++) {
printf("%c", words[j]);
}
} else {
// Print the last word
for (int j = 0; j < space_indices[0]; j++) {
printf("%c", words[j]);
}
}
}
}
As Havenard explained, the problem was that I was not using a comparison operation, I was using an assignment operator.
This:
if ( i = counter - 1)
should be:
if ( i == counter - 1)
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I'm receiving Output: 1. I should count the number of times a digit appear in an integer, for example, for number 1222345 and n = 2 Should appear 3 times.
int countOccurrences(int n, int num)
{
int i,k;
i=0;
while(num!=0)
{
k=num%10;
num=num/10;
if(k==n)
{
i++;
}
}
}
// Main
void main()
{
int num= 1222345;
int n = 2;
printf("Occurance of a number: %d", countOccurrences(n,num));
}
You have undefined behavior in the code. The function is supposed to return an int and it didn't.
Solution is to add return i in the end of other function. This will give you correct result. In the countOccurrences() function
...
if(k==n)
{
i++;
}
}
return i;
}
I was skipping the discussion of error check and all that. As chux mentioned for n<=0 case you might want to add a different way of handling it but you didn't add it. Atleast consider those case and put an error message on whatever input you need.
Some corner cases are
n=0,m=0.
Negative value of n or m.
Put a return on your countOccurrences function please
int countOccurrences (int n, int num) {
int i, k;
i = 0;
while (num! = 0)
{
k = num% 10;
num = num / 10;
if (k == n)
{
i ++;
}
}
return i; }
As other have pointed out, there are important issues with your code.
Here is a recursive solution that you may find interesting:
int countOccurrences(int n, int num)
{
int count = ((num % 10) == n);
return (num < 10) ? count : count + countOccurrences(n, num / 10);
}
Few general remarks about your code:
When using printf(), you should #include <stdio.h>.
main() should return int.
Place spaces around operators and format your code consistently. This k = num % 10; is more readable than k=num%10;. (There's more to code formatting than a matter of taste; without spaces you create areas full of characters which are more difficult to parse for our visual system.)
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
int main()
{
int a,query,in,n,b[n],sum[a];
sum[1]=0;
scanf("%d",&query);
for(a=1;a<=query;a++)
{
scanf("%d",&in);
for(n=1;n<=in;n++)
{
b[n]=1+7*(n-1)+6*(n-1)*(n-2)+(n-1)*(n-2)*(n-3);
sum[a]=sum[a]+b[n];
}
}
for(a=1;a<=query;a++)
{
printf("%d\n",sum[a]);
}
return 0;
}
I have made this code which is running in terminal .
But in hacker rank it is showing
Input (stdin)
2
2
5
Your Output (stdout)
~ no response on stdout ~
Expected Output
9
225
Compiler Message
Segmentation Fault
Now what should I do to solve the problem .
Your variables are uninitialized. As a result your program invokes Undefined Behavior.
For example you do not initialize n, but you then declare int b[n]. What is the size of array b? Nobody really knows, since n has a garbage value.
Start by figuring out what the values of your variables should be, and then start coding.
Array indexing starts from 0, thus your for loops are not looking good.
Change this:
for(a=1;a<=query;a++)
to this:
for (a = 0; a < query; a++)
int main()
{
int a, query, in, n, *b, *sum;
scanf("%d",&query);
sum = malloc(query * sizeof(int));
/* do some checks if the malloc was successful */
for(a = 0; a < query; a++)
{
scanf("%d",&in) ; /* you should check if scan has returned 1 */
b = malloc(in * sizeof(int)); /* and again check against any allocation errors */
for(n = 0; n < in; n++)
{
b[n] = 1+7*(n)+6*(n)*(n-1)+(n)*(n-1)*(n-2);
sum[a] = sum[a] + b[n];
}
free(b);
}
/* the rest */
In int a,query,in,n,b[n],sum[a];, the value of a is not initialised and is having garbage value which could be anything. This value is used as the size of the variable length array sum. So the size of the array could be anything which is probably not what you want.
a could be 0 in which case sum is an array of size 0 which will in turn make sum[1] incorrect (it would be undefined behavior).
The same applies to n and b[n].
In the nested for loop, with sum[a]=sum[a]+b[n]; you are using sum[a] which has not been initialised. It has garbage value and the result is indeterminate.
If you wanted all elements of sum to be initialised with 0, you can do
int sum[20]={0};
at the time of declaring it.
The same goes for b[n]=1+7*(n-1)+6*(n-1)*(n-2)+(n-1)*(n-2)*(n-3); as well.
And array indexing starts at 0.
Perhaps you could use the loops like
for (a = 0; a < query; a++) {
instead of
for (a = 1; a <= query; a++)
If you choose the starting index as 0, the inner nested loop should be like
for(n=0;n<in;n++)
{
//b[n]=1+7*(n-1)+6*(n-1)*(n-2)+(n-1)*(n-2)*(n-3);
b[n]=1+7*(n)+6*(n)*(n-1)+(n)*(n-1)*(n-2);
sum[a]=sum[a]+b[n];
}
See demo.
Your problem is in this line:
int a,query,in,n,b[n],sum[a];
What is the meaning of b[n]? And of sum[a]? Assuming that you would like to have a language with magically growing arrays, C is a bad choice.
In C language arrays are a structure with size known at compile time. Anyway, let's assume that your compiler supports the horrible hack of variable-length arrays. You can do this:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main(void) {
int a, query, in , n;
scanf("%d", &query);
int sum[query+1];
for (a = 1; a <= query; a++) {
sum[a] = 0;
scanf("%d", &in);
int b[in+1];
for (n = 1; n <= in ; n++) {
b[n] = 1 + 7 * (n - 1) + 6 * (n - 1) * (n - 2) + (n - 1) * (n - 2) * (n - 3);
sum[a] = sum[a] + b[n];
}
}
for (a = 1; a <= query; a++) {
printf("%d\n", sum[a]);
}
return 0;
}
Note the changes: first you need to know the size of the array, then you can allocate it. Moreover, I increased the size of the array in order to support your choice of starting from 1. Lastly I also zeroed the initial value for sum array.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
Working on a project Euler problem (#10), I've an interesting compile error. My compiler tells me I need a semicolon. The exact error is 49: ';' expected.
Now I know this is not unusual with C code, but the problem is I've triple checked all semicolons and parentheses and brackets, and none are missing. Not even in loops. Chances are I'm just missing it.
HOWEVER
The compiler tells me 49: ';' expected - but the code on line 49 is just one bracket ({).
Would anyone have any insight into what might be wrong here?
Code is as follows:
// this is a program to find the sum of all primes below 2 million
// uses the Seive of Eratosthenes
#include <stdio.h>
int main() {
long int sum = 0;
long int s = 2000000; // size of array
long int i; // 'for' loops
long int n; // number to test
long int a; // prime checker
long int multiples;
long int* array; // define pointer for calloc int array
// calloc the array
array = (int*)calloc(s, sizeof(int)); // allocates 2,000,000 spots (s) of
// size "int" to array "array"
// set all array values equal to 1
for (i = 0; i < 2000000; i++) {
array[i] = 1;
}
/*
VALUES IN ARRAY
The values of the array indicates whether number-
(0) IS PRIME
(1) UNTESTED
(2) IS COMPOSITE
*/
// implement prime finder
for (n = 0; n < 2000000; n++) {
if (array[n] == 0) // IF n IS PRIME
{
multiples = n;
multiples += n;
while (multiples < 2000000) {
array[multiples] = 2;
multiples += n;
}
} else
(array[n] == 2) // IF n IS COMPOSITE (is a multiple)
{ // THIS IS LINE 49
continue;
}
else(array[n] == 1) // UNTESTED
{
for (a = 2; a < n; a++) // double checks for composites
{
// tests factors
if (n % a == 0) {
printf("ERROR");
goto end;
}
}
array[n] = 0;
multiples = n;
multiples += n;
while (multiples < 2000000) {
array[multiples] = 2;
multiples += n;
}
}
}
// read array and sum primes
for (n = 0; n < 2000000; n++) {
if (array[n] == 0) // IF n IS PRIME
{
sum += n;
} else
(array[n] == 2) // IF n IS COMPOSITE
{
continue;
}
else(array[n] == 1) // IF n MAY/MAY NOT BE PRIME
{
printf("ERROR");
goto end;
}
}
printf("The sum of all primes < 2,000,000 is... %ld!\n", sum);
end:
getchar();
return 0;
}
Change the else to else if and you are fine.
And do that with all the else.
else( array[n] == 2) // IF n IS COMPOSITE (is a multiple)
{ //THIS IS LINE 49
else doesn't take a condition. The else should be else if.
The compiler's syntax recovery tries to suggest the simplest change that would result in a syntactically valid program. Often the suggested change doesn't make much sense. In this case, adding a ; after the else would turn the following ( array[n] == 2) into the beginning of an expression statement (which would have to be followed by another semicolon).
If your code produces a syntax error message, the best approach is often to ignore the suggestion it makes and just look at the line it refers to and the line(s) preceding it, and figure out what's wrong with the syntax at that point. Then fix the error and recompile.
You're really missing is some ifs to go with your elses:
if( array[n] == 0) // IF n IS PRIME
{
sum += n;
}
else if( array[n] == 2) // IF n IS COMPOSITE
{
continue;
}
else if( array[n] == 1) // IF n MAY/MAY NOT BE PRIME
{
printf("ERROR");
goto end;
}
It's pretty easy to confuse a compiler like this, and when you do, some of its error messages can get hard to understand.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
Assume the character a,b,c,d,e represent the number 1 to 9, and they cannot be equal to
each other.
Question:
How many equals that can meet (ab * cde = adb * ce).
Example:
36 * 495 = 396 * 45.
Here is my code,and the result is right.However,i think my code is too awkward,especially in (if(a!=b&&a!=c&&a!=d&&a!=e&&b!=c&&b!=d&&b!=e&&c!=d&&c!=e&&d!=e&&c*d*e!=0))
I would appreciate it if someone could give me a better solution.
#include<stdio.h>
main(){
int a,b,c,d,e,m,n,i=0;
long f1,f2,f3,f4;
for(m=11;m<=99;m++){
a=m/10;
b=m%10;
if(a!=b&&a*b!=0)
{
for(n=101;n<=999;n++)
{
c=n/100;
d=n%100/10;
e=n%10;
if(a!=b&&a!=c&&a!=d&&a!=e&&b!=c&&b!=d&&b!=e&&c!=d&&c!=e&&d!=e&&c*d*e!=0)
{
f1=a*10+b;
f2=c*100+d*10+e;
f3=a*100+d*10+b;
f4=c*10+e;
if(f1*f2==f3*f4) i++;
printf("\n%d%d*%d%d%d*=%d%d%d*%d%d\n",a,b,c,d,e,a,d,b,c,e);
}
}
}
}
printf("%d\n",i);
return 0;
}
If you can, instead of
int a,b,c,d,e;
Try to use
int numbers[5];
And then to check if your numbers are all different, you can use for loops
doubleOccurence = FALSE; /* where FALSE = 0 */
for (i=0; i < 4; i++) {
for (j=i+1; j < 5; j++) {
doubleOccurence = doubleOccurence || (numbers[i] == numbers[j]);
}
}
It looks a bit clearer to me.
Unfortunately you can't really iterate through a list of variables you are better off with an array of numbers like Julien mentions in his answer.
int nums[5];
replace a with nums[0], b with nums[1], etc....
But then I would go one step further to tidying up your code and call a function that takes in the array to check uniqueness:
if(listIsUnique(nums, 5)) // yes hardcoded the 5, but that can be sorted
{
...
}
And then:
bool listIsUnique(int* nums, int len)
{
for (int i = 0; i < len; i++)
for (int j = i + 1; j < len; j++)
if (nums[i] == nums[j])
return false; // return false as soon as you find a match - slightly faster :)
return true; // if we get here its a unique list :)
}
Note: code is untested, there may be mistakes :o