Very anomalous behaviours by C++ compiler - c++

I have the following code. In the function xyz(int from, int to, int i). I am printing the value of i and i*2+1. But I am getting unexpected output with i = 1 and i*2+1 = -1.
The function xyz2() is exactly the same except that I have uncommented a dummy function call and I am getting the expected output with i = 0 and i*2+1 = 1. Please see the output as I have explained it. Also I would mention that I get the same output on my local machine.
Why is this happening?
#include <stdio.h>
#include <stdlib.h>
long long arr[2];
long long xyz(int from, int to, int i);
long long array[200000];
long long xyz2(int from, int to, int i);
long long foo(){return 141;}
int main(){
int n=2;
arr[0] = -4;
arr[1] = 5;
xyz(0, 1, 0);
printf("\n\n");
xyz2(0, 1, 0);
return 0;
}
long long xyz2(int from, int to, int i){
if(from==to){
return arr[to];
}else{
int mid = (from+to)/2;
array[i*2+1] = xyz2(from, mid, i*2+1);
array[i*2+1] = foo();
printf("%d %d\n", (i*2)+1, i);
return 100000;
}
}
long long xyz(int from, int to, int i){
if(from==to){
return arr[to];
}else{
int mid = (from+to)/2;
array[i*2+1] = xyz(from, mid, i*2+1);
//array[i*2+1] = foo(); // The above function xyz2 gives the
//correct results on uncommenting this line
printf("%d %d %d\n",array[i*2+1], (i*2)+1, i);
return 100000;
}
}

printf("%d %d %d\n",array[i*2+1], (i*2)+1, i);
The first data argument is a long long. You need to change your format string to match:
printf("%lld %d %d\n",array[i*2+1], (i*2)+1, i);
The reason you're getting weird behaviour when the wrong conversion specification is used is because the behaviour is undefined:
C99 ยง7.19.6.1/9 If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
This comes from the specification for fprintf, which printf is defined in terms of. The C99 standard is normative for C++11.

This line in xyz2(..):
printf("%d %d %d\n",array[i*2+1], (i*2)+1, i);
is NOT the same as this line in xyz(..)
printf("%d %d\n", (i*2)+1, i);
Changing the commented out line changed the result as follows:
With Line Commented
-4 1 0
1 0
With Line Uncommented
141 1 0
1 0
I don't seem to be getting any strange output (I think) using XCode 5....but I AM getting warnings about the format of the printed string:
printf("%d %d\n", (i*2)+1, i);
should be
printf("%lld %d\n", (i*2)+1, i);
Using long long requires a special print format, I believe. This could be the problem...

Related

long long int don't take long int well

When a friend of mine asked me to debug the problem with a console game project I had found a weird conversion of fprintf in C that I can't figure out. The project was required to keep track of all the information, including scores and update time to a .txt file using C.
-Initialization
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
.
.
.
// in main
time_t timer;
time (&timer);
int num=0,c;
scanf(" %s %ld", inputname,c);
fscanf(fp, "%d", &num);
num++;
char **name;
long *times;
ull *score;
name = new char *[num];
for(int i=0; i<num; i++){
name[i] = new char[MAX];
}
times = new long [num];
score = new ull[num];
//new data
name[num-1] = inputname;
score[num-1] = c;
times[num-1] = timer;
-The I/O parts
.
.
.
// input from file after dynamic variables have fix size
for(int i=0; i<num-1; i++){
fscanf(fp, " %s%d", name[i], &score[i]);
fscanf(fp, "%ld", &times[i]);
}
fseek(fp , 0 , SEEK_SET);
fprintf(fp, "%d\n", num);
//print back to fp
for(int i=0; i<num; i++){
fprintf(fp, "%s %ld ",name[i], score[i]);
fprintf(fp, "%ld\n",times[i]);
}
Problem. if I change
fprintf(fp, "%s %ld ",name[i], score[i]);
fprintf(fp, "%ld\n",times[i]);
to one-line
fprintf(fp, "%s %ld %ld\n",name[i], score[i],times[i]);
the output file will have
NAME1 SCORE1 TIMEINLONG1
NAME2 SCORE2 0
NAME3 SCORE3 0
.
.
.
instead of
NAME1 SCORE1 TIMEINLONG1
NAME2 SCORE2 TIMEINLONG2
.
.
.
After some trying, I found that by reversing the order of scores and times
fprintf(fp, "%s %ld %ld\n",name[i], times[i],score[i]);
I have a correct output
NAME1 TIMEINLONG1 SCORE1
.
.
.
again.
So, how exactly does C do with output stream. I thought the compiler collect the argument in "..." to assemble a string, then flush it to outputstream. Obviously it ignored the time[i] after the first (time[0]).
Is it the problem of the way I intialize times[]?
Or is it the problem with fprintf()?
Apology for such a lengthy page, but I'm really confused about the fprint now.
Solved
edit title from "fprintf with dynamic memory" to "long long int don't take long int well, vise versa."
The problem was not on the dynamic memory things(Sorry I didn't know), but was the type that I used to get and put data in printf, fprintf, scanf, fscanf. According to #Adrian Mole , the mismatch assign long int to a long long int type variables was undefined behavior, and the following I/O action will not be correctly done. It seems that even long long int have more space than those of long long, it is not compatible.
No
long long int c;
scanf("%d",&c);
printf("%d",c);
//or
scanf("%ld",&c);
printf("%ld",c);
Yes
long long int c;
scanf("%lld",&c);
printf("%lld",c);
You have here a classic example of "undefined behaviour!" The variable that is score[i] is (assuming a reasonable definition of the type ull) an unsigned long long int (possibly/probably 64-bits) but both the scanf and 'offending' printf calls use the %ld format specifier (possibly/probably referring to a 32-bit variable).
When printf is called with a "mismatch" between the format specifier and the given argument, you are in undefined behaviour territory!
Fix the issue by specifying the %llu format for the corresponding score[i] argument! For example, in place of:
fprintf(fp, "%s %ld %ld\n",name[i], score[i],times[i]);
use:
fprintf(fp, "%s %llu %ld\n", name[i], score[i], times[i]);
// score[i] is ull ^ | ^ OK - times[i] is (signed) long!
Feel free to ask for further clarification and/or explanation.
The problems start at the following lines:
int num=0,c;
scanf(" %s %ld", inputname, c);
First, you should write &c instead of c as the last parameter. Since scanf writes into its parameters, it should receive addresses of parameters (except strings, I am too lazy to explain why).
Second, since c is int, you need %d, not %ld. Be careful with sizes.
As for your fprintf - again, be careful with sizes. Since score is ull*, and I assume that ull means unsigned long long, you need to print it with %llu format, not %ld. (Note - Andrian Mole also pointed this piece, and posted his answer slightly before I posted mine.)
Another error is:
name[num-1] = inputname;
That reassigns the pointer to heap allocated memory and causes a memory leak. inputname array should be copied into name[n] array, e.g.,
snprintf(name[num-1], MAX, "%s", inputname);
scanf %s may overflow its destination array argument, unless you hard-code the destination size, e.g.:
#define MAX 256
int num=0,c;
char inputname[MAX];
scanf("%256s %d", inputname, c);

Wrong outputs in Decimal to binary conversion after input of 1024?

My code works fine till 1024, but bigger values than 1024 gives wrong output, please help:
#include<stdio.h>
int main()
{
int dec,i=1;
int rem=0;
long long int result=0;
scanf("%d",&dec);
while(dec!=0)
{
rem=dec%2;
result = result +rem*i;
dec=dec/2;
i=i*10;
}
printf("%I64u",result);
return 0;
}
The code should accumulate the binary value in a string. Since this is cross-posted to C and C++, I suppose a C solution is appropriate (in C++ I'd use std::string, and the bookkeeping would be somewhat simpler):
#include<stdio.h>
int main()
{
int rem=0;
char result[sizeof(long long)*CHAR_BITS+1];
int dec,i=sizeof(result);
result[--i] = '\0';
scanf("%d",&dec);
while(dec!=0)
{
rem=dec%2;
result[--i] = rem + '0';
dec=dec/2;
}
printf("%s",result + i);
return 0;
}
(Caution: not tested)
Here you are
#include <stdio.h>
int main(void)
{
int dec = 0;
long long int i = 1;
long long int result = 0;
scanf( "%d", &dec );
do
{
int rem = dec % 2;
result = result + rem * i;
i *= 10;
} while ( dec /= 2 );
printf( "%I64u", result );
return 0;
}
The problem is that the variable i is declared as having the type int. So the result value of the expression i *= 10 or of the expression rem * i will be calculated as objects of the type int not as objects of the type long long int.
If to enter 1024 then the output is
10000000000
In general your approach is wrong because the size of the type long long int in any case is restricted and will be unable to represent all posible integer values in the binary notation.
You could use either a character or an integer array of digits instead of an object of the type long long int.

Runtime error while adding printf statement [closed]

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 7 years ago.
Improve this question
Why it is giving runtime error while adding printf statement in the last? And just after the removing the printf statement, no error.
#include <stdio.h>
#define MOD 1000000007
#define MAX 44721
int main() {
long long int test, i, j, store[1000009], n, m, x, a[1000006];
scanf("%lld", &test);
for (i = 0; i < 1000006; i++) {
store[i] = 1LL;
}
a[0] = 1;
for (j = 1; j < 1000006; j++) {
for (i = 1; i < MAX; i++) {
if (i % 2 == 0) {
store[i] = (store[i - 1] + store[i]) % MOD;
}
}
a[j] = store[MAX - 1];
}
printf("%lld", a[1]);
return 0;
}
First of all you should pick a language as C is different from C++.
As your code is C my solution will be in C too.
Running your code under Valgrind cleary shows that you are experiencing a stack overflow. The size of the arrays on the stack are too big.
Valgrind output:
==14228== Invalid write of size 4
==14228== at 0x100000DC7: main (prova.c:6)
==14228== Address 0x1038c062c is on thread 1's stack
==14228== in frame #0, created by main (prova.c:6)
The size of the stack is system-dependent, the default on many system is 8MB, on unix/linux you can see it issuing the commnad ulimit -a. You may want to look at this post for more information about how stack and heap works.
The correct solution is to allocate arrays dynamically:
store = malloc(1000009 * sizeof(long long int));
if (store == NULL) {
// The memory allocation failed, exit
return(1);
}
a = malloc(1000006 * sizeof(long long int));
if (a == NULL) {
return(1);
}
Remember to always check the return value of malloc ;)
You allocate 2 large arrays of long long int in automatic storage, that's more than 8MB of stack space. You probably cause a stack overflow. It is possible that the compiler optimizes out most of your code if you remove the printf since none of it has any observable behavior without it.
In C, allocate the arrays with malloc:
#include <stdio.h>
#define MOD 1000000007
#define MAX 44721
int main(void) {
long long int test, i, j, n, m, x;
long long int *store = malloc(1000009 * sizeof(*store));
long long int *a = malloc(1000006 * sizeof(*a));
scanf("%lld", &test);
for (i = 0; i < 1000006; i++) {
store[i] = 1LL;
}
a[0] = 1;
for (j = 1; j < 1000006; j++) {
for (i = 1; i < MAX; i++) {
if (i % 2 == 0) {
store[i] = (store[i - 1] + store[i]) % MOD;
}
}
a[j] = store[MAX - 1];
}
printf("%lld", a[1]);
return 0;
}
There's 2 main problems here.
Your code is probably failing because of retrun 0; (fix: return 0;)
Second, you are allocating 2 really big array in the stacks, and you will, 99% of the times, end up getting stack overflow;
Note: long long int, is the same as long long:
You should consider using:
std::vector<long long> store(10000009);
or
std::unique_ptr<long long[]> store = std::make_unique<long long[]> (10000009);
or
long long* store = new long long[10000009]
or
auto* store = new long long[10000009]
or if you are using c... since you have both tags
long long* store = (long long *)malloc(sizeof(long long) * 10000009);
or if you are using MSVC, you can use the __int64 keyword if what you want is a int of 64 bits [8 bytes])
std::vector<__int64> store(1345134123);
I normally prefer that over long long
And you could do a typedef long long __int64 if you end up using another compiler.

Floating Point Exception Error

This program compiles fine, but it returns a message "Floating Point Exception" when I run it. I've looked at other threads and the problem appears to be dividing by 0, but I have looked over the program and there's no division by zero in my entire program. I even used the absolute value function in case.
By the way, the program is meant to reduce fractions.
Example input: 6 12, representing the fraction 6/12
Expected output: 1/2
#include <stdio.h>
/*declaring variables*/
int num1, num2, num1b, num2b, gcd, x;
int higher, lower, higher_2, lower_2;
/*declaring functions*/
int find_gcd(int num1, int num2);
void reduce(int numerator, int denominator, int *reduced_numerator, int *reduced_denominator);
int main(void)
{
do
{
printf("enter 2 numbers: ");
scanf("%d %d", &num1, &num2);
reduce(higher, lower, &higher_2, &lower_2);
printf("enter 0 to end program and any number continue: \n");
scanf("%d", &x);
} while(x != 0);
return 0;
}
void reduce(int numerator, int denominator, int *reduced_numerator, int *reduced_denominator)
{
num1=numerator;
num2=denominator;
gcd =find_gcd(numerator, denominator);
*reduced_numerator = (numerator/abs(gcd));
*reduced_denominator = (denominator/abs(gcd));
printf("The GCD is %d/%d\n", *reduced_numerator, *reduced_denominator);
}
int find_gcd(int m, int n)
{
while (n != 0) {
int remainder = m % n;
m = n;
n = remainder;
}
return m;
}
Your main problem is that you are not passing your input values num1 and num2 into your reduce() function. Instead you are passing in the global variables higher and lower. You didn't assign any values to them, but global variables are always initialized to 0 by default. Therfore, you run into the exception, because in reduce() you divide 0 by 0. You can verify that with a debugger.
If I change your main() as follows, then your code is at least working for your test case with 6 and 12 as input:
int main(void)
{
do
{
printf("enter 2 numbers: ");
scanf("%d %d", &num1, &num2);
reduce(num1, num2, &higher_2, &lower_2);
printf("enter 0 to end program and any number continue: \n");
scanf("%d", &x);
} while(x != 0);
return 0;
}
Output:
enter 2 numbers: 6
12
The GCD is 1/2
enter 0 to end program and any number continue:
As indicated in the comments you should also get rid of global and spurious variables. Therefore, you should first delete the following lines in your code:
/*declaring variables*/
int num1, num2, num1b, num2b, gcd, x;
int higher, lower, higher_2, lower_2;
Then let your main() function start the following way:
int main(void)
{
int num1, num2, higher_2, lower_2, x;
...
}
And your reduce() function should read like this:
void reduce(int numerator, int denominator, int *reduced_numerator, int *reduced_denominator)
{
int gcd = find_gcd(numerator, denominator);
*reduced_numerator = (numerator/abs(gcd));
*reduced_denominator = (denominator/abs(gcd));
printf("The GCD is %d/%d\n", *reduced_numerator, *reduced_denominator);
}
So far, you don't use your variables higher_2 and lower_2 in the main() function, but I guess you plan to do so. If not, you can also get rid of them together with parameters 3 and 4 of your reduce() function.
There is another issue with the code you provided (thanks to #user3629249 for pointing it out): You are missing an include for the abs() function. So you need to add the line #include <stdlib.h> at the beginning of your code (include <math.h> will also so the trick, as well as include <Windows.h> on Windows).

Code blocks issues

Hi i'm doing a piece of coursework and im having difficulty with an error messages that i'm getting, they are:
error 'strtoul' was not declared in this scope
error 'print' was not declared in this scope
error 'printf' was not declared in this scope
the code ive entered is:
using namespace std;
int main (int argc, const char * argv[]) {
unsigned long int a, tmp;
a = strtoul("01011111000110001001001011010011",ULL,2);
print(a);
//We always work on "a" pattern
print(tmp = a >> 4);
print(tmp = a << 6);
print(tmp = a & (long int) 0x3);
print(tmp = a & (char) 0x3);
print(tmp = a | (unsigned short) 0xf00f);
print(tmp = a ^ (long int) 0xf0f0f0f0);
return 0;
}
//Function prints unsigned long integer in hexadecimal and binary notation
void print(unsigned long b)
{
int i, no_bits = 8 * sizeof(unsigned long);
char binary[no_bits];
//Print hexadecimal notation
printf("Hex: %X\n", b);
//Set up all 32 bits with 0
for (i = 0; i < no_bits; i++) binary[i] = 0;
//Count and save binary value
for (i = 0; b != 0; i++) {
binary[i] = b % 2;
b = b/2;
}
//Print binary notation
printf("Bin: ");
for (i = 0 ; i < no_bits; i++) {
if ((i % 4 == 0) && (i > 0)) printf(" ");
printf("%d", binary[(no_bits - 1) - i]);
}
printf("\n\n");
}
But i keep getting the error mesage:
error 'strtoul' was not declared in this scope
error 'print' was not declared in this scope
error 'printf' was not declared in this scope
no matter what i try i keep getting the same error messages when i try and declare them, any help out there??
Much appreciated,
Ben
You need to include these header files at the top of your program:
#include <stdlib.h>
#include <stdio.h>
The stdio library allows you to do input/output operations and the stdlib library defines several general purpose functions, including converting a string to unsigned long integer.
You will want to move your print method before main and you should also change ULL to NULL when you call strtoul as I believe that was a typo. You can check out the documentation in the link I provided.