Greetings Everyone
I am currently trying to write a multi-language program (C, C++ and fortran) though am achieving segmentation errors. I've ruled out vectors and the like in: Accessing public class memory from C++ using C
I've narrowed now the cause to the use of 'cout' experssions in my C++ segments and printf(...) in C segments. Depending on which order I run these at I always get segmentation error when using the 2nd type, like so:
cout first, then printf(...) will crash at first C output function
printf(...), then cout will crash at first C++ output function
I am #include <iostream> in my C++ sources, and #include <stdio.h> & #include <stdlib.h> in my C sources.
Is there a library conflict that I am not aware of?
Requested code:
main.cpp
#include <iostream>
#include <vector>
#include "CFE.h"
ios::sync_with_stdio(true);
using namespace std;
vector<float> DensityArray;
vector<float> EnergyArray;
int main()
{
int X = ReturnX ();
int Y = ReturnY ();
cout << "X " << X << endl;
cout << "Y " << Y << endl;
EnergyArray.resize(Y*X);
DensityArray.resize(Y*X);
CFE(&DensityArray[0], &EnergyArray[0]);
cout << "X " << X << endl; //causes Segmentation break
cout << "Y " << Y << endl; //causes Segmentation break
system ("PAUSE");
return 0;
}
CFE.h
#ifdef __cplusplus
extern "C" {
#endif
int ReturnX ();
int ReturnY ();
void CFE(float density[], float energy[]);
#ifdef __cplusplus
}
#endif
CFE.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "BCs.h"
#include "EMatrix.h"
#include "Numbering.h"
#include "KMatrix.h"
#include "fg_types.h"
#include "Solve.h"
int ReturnX ()
{
FILE *infile;
infile = fopen("test05", "r");
int elemX,elemY;
fscanf(infile, "%i %i", &elemX, &elemY);
fclose(infile);
return elemX;
}
int ReturnY ()
{
FILE *infile;
infile = fopen("test05", "r");
int elemX,elemY;
fscanf(infile, "%i %i", &elemX, &elemY);
fclose(infile);
return elemY;
}
void CFE(float density[], float energy[])
{
FILE *infile;
infile = fopen("test05", "r");
int elemY, elemX;
fscanf(infile, "%i %i", &elemX, &elemY); //Will cause Segmentation break
int n;
float * dens;
dens = density;
float * engy;
engy = energy;
int Length = 10;
for ( n = 0; n < Length; n++)
{
engy[n] = n;
}
}
You need to check that the files are opened correctly - i.e. the the pointer returned by fopen() is not NULL. Also,
int ReturnY ()
{
FILE *infile;
infile = fopen("test05", "r");
int elemX,elemY;
fscanf(infile, "%i %i", &elemX, &elemY);
return elemX;
}
I take it return elemx should be return elemy?
Any particular reason why you don't just use printf in your C++ code? Sure, it's not like what all the cool kids do, but it should still work.
What platform is this on? If you have ios::sync_with_stdio(bool) available on your platform, call it with
ios::sync_with_stdio(true)
at the beginning of your program (call it from C++). Does this help?
When I mix cout and printf in an application, I find it useful to have all my C++ code do the equivalent of:
fflush(stdout);
cout << ...whatever... << flush;
This way stdout and cout never both have unflushed buffers at any point in time.
Extra care should be taken for apps where multiple threads access stdout and/or cout.
The quick answer here is no, it absolutely 100% should not crash just because you are mixing printf and cout. The only difficulty with mixing the two is that the respective output buffers will not be synced by default, so the order of the output may be a bit mixed up. But it definitely should not crash.
At a quick guess, perhaps you have a formatting problem with printf -- you're passing a double when it expects a short int, or something like that. That will lead to unpredictable problems, which might well shift depending on the order of function calls in your code.
ReturnY() is returning X instead of Y
(ps. close your files)
I don't see a printf(), so I can't comment on it. You should show what printf()s you're using, providing a complete sample program that fails as you describe.
As far as the comment about a crash on fscanf(), as Neil Butterworth says, you need to check the return value of fopen(). If, for some reason, the fopen() fails (which it doesn't look like it should), fscanf() might crash. (If it can't read integers, it should deal with it.) You're not checking anything in I/O. (Alternatively, the I/O system might be messed up from something previous.)
I'd suspect corruption somewhere in the I/O memory, but I don't see enough to conclude anything.
Related
I am trying to do some file reading with C++ in Ubuntu 16.04 (GCC&G++ 5.4 and CMake 3.5.1).
The test file (named 123.txt) have only a line words just like this:
Reprojection error: avg = 0.110258 max = 0.491361
I just want to get the avg error and max error. My method is to get a line and put them into a std::string
and use string::find. My codes are very easy just like this:
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
int main()
{
FILE *fp = fopen("123.txt", "r");
char tmp[60];
string str;
fgets(tmp, size_t(tmp), fp);
fclose(fp);
cout << tmp << endl;
str = tmp;
cout << str.size() << endl;
size_t avg = str.find("avg");
size_t max = str.find("max");
cout << avg << endl;
cout << max << endl;
}
I can use g++ to compile it successfully. But I meet a strange issue.
When I first run it in the command, it will get the right result:
Reprojection error: avg = 0.110258 max = 0.491361
52
20
37
If I run codes again, it will go wrong sometimes just like this:
p
2
18446744073709551615
18446744073709551615
The "p" is a disorderly code which can not be shown correctly in the command. I am not good at C++ and feel confused about it. Is there someone who can say something? Thank you!
The expression
fgets(tmp, size_t(tmp), fp);
is ill-formed, size_t(tmp) will not work as you expect, you need sizeof(tmp).
The 52 value you get is because fgets consumes the \n character and this is counted too, actually the string has 51 characters counting with spaces.
That said, in this case you can use better C++ tools to replace the C ones you are using, fopen can be replaced by using the fstream library, fgets can be replaced by getline.
Something like:
#include <iostream>
#include <string>
#include <fstream>
int main()
{
std::ifstream fp("123.txt"); //C++ filestream
if (fp.is_open()) {//check for file opening errors
std::string str;
std::getline(fp, str); //C++ read from file
fp.close();
std::cout << str << std::endl;
std::cout << str.size() << std::endl;
size_t avg = str.find("avg");
size_t max = str.find("max");
std::cout << avg << std::endl;
std::cout << max << std::endl;
}
else{
std::cerr << "Couldn't open file";
}
}
Note that I dind't use using namespace std;, this is for a reason, it's not a good practice, you can check this thread for more details.
Im having this really weird error during run-time.
My program takes two parameters, does some math calculus with them and std::cout's the values in the end.
My program works if i input somevalues, but if i input other values it says that a variable is being used without being initialized, which i think it makes no sence.
Here is the code:
#include <iostream>
#include <stdio.h>
#include <cmath>
double align_nb(int n) { return { ceil(n / 512.0)*512.0 }; } // bytes
double align_pt(int k) { return { floor(k / 512.0)*512.0 }; } // pointer
int main(int argc, char * argv[])
{
int o_n = std::atoi(argv[1]); // original number
int o_p = std::atoi(argv[2]); // original pointer
int max_bytes, new_pointer; // max bytes to read, new pointer to point
float log = (std::log(o_n) / std::log(2));
if (log != floor(log))
{
max_bytes = align_nb(o_n); // bytes alinhados para a frente
new_pointer = align_pt(o_p); // ponteiro alinhado atrĂ¡s
}
else if (log == floor(log))
{
new_pointer = align_pt(o_p);
if (max_bytes + (o_p - new_pointer) >max_bytes)
{
max_bytes += 512;
}
}
std::cout << "Original bytes= " << o_n << std::endl;
std::cout << "Original pointer= " << o_p << std::endl;
std::cout << "Max_bytes= " << max_bytes << std::endl;
std::cout << "new_pointer= " << new_pointer << std::endl;
return 0;
}
Here are the values i tested it and it crashed, giving me that run-time error:
2048 513
1024 500
here is one example of values were the code doesnt give me that error and the program works:
513 520
Here is a print of the error it gives me.
I'd really appreciate someone explaining me why it gives me that error/how to fix it.
Regardless, thanks!
(PS: math tag is included cause it could be the math in the program that is causing it to crash. If annyone thinks it shoudlnt be used in this question, let me know in the comments and ill remove it.)
(PS 2: the variable it complains when it gives me the run time error is 'max_bytes'.)
If your code takes the else path at line 17, then your code doesn't initialize max_bytes, but uses it afterwards. That's the problem.
Notes:
comparing calculated floating point values for equality usually a bad practice
you don't need the additional if at line 23.
Make sure that for each path your code takes the values of the variables you use are initialized. If you don't you get what is called Undefined Behaviour. There could be anything in an uninitialized variable.
int max_bytes;
....
....
expression_involving_max_byte <- Dangerous!
This beginner's program I am trying to make is basically a program where a truly random number is generated and the "player" has to guess the number. The computer will respond "too high" or "too low" until the player guesses the right number.
I got this program idea from some website, and thought I should roll with it. This is my second program- my first being a simple I/O program.
Here is my code:
// BracketingSearch.cpp
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <string>
#include <ctime>
#include <istream>
#include <fstream>
using namespace std;
int main()
{
int x = srand(time(0));
cout << x << endl;
for (int x = 1; x <= 10; x++) {
cout << 1 + (rand() % 100) << endl;
}
string stall;
getline(cin, stall);
}
Side notes:
I don't think I need that many headers; I am still getting use to the c++ libraries.
Please critique my code as much as possible. I am eager to learn programming!
The string stall is just to make my console application pause for input, so I can see the results.
Thank you for everyone who can help!
-Mike
srand(time(0)) seeds the random number generated by rand(). Its return type is void. void type cant be stored in an integer type variable.
See here for more information on srand().
I rewrote the program to use the minimum of headers required. Since I think this is homework, I left the original error in place, but placed the error output from gcc here.
#include <iostream>
#include <cstdlib>
#include <ctime>
// this is a personal thing, but I avoid "using namespace std;"
// in any file, since it makes it less clear where some symbols
// came from
int main()
{
int x = std::srand(std::time(0)); // line 11
std::cout << x << std::endl;
for (int x = 1; x <= 10; x++) {
std::cout << 1 + (std::rand() % 100) << std::endl;
}
// Windows folklore -- you should better switch your ide to not close
// the terminal after the program was run
std::cin.get();
}
The output of g++ -Wall foo.cpp:
foo.cpp: In function 'int main()':
foo.cpp:11:40: error: void value not ignored as it ought to be
int x = std::srand(std::time(0));
^
I was trying out some c++11 code, and I tried to write a program that counts down from 10, sleeping in between the outputs. Here's what I have so far:
#include <iostream>
using namespace std;
#include <chrono>
#include <thread>
void Sleep(int x)
{
std::this_thread::sleep_for(std::chrono::duration<int>(x));
}
int main()
{
for (int x=10; x>0; x--) {
cout << x << "...";
Sleep(1);
}
cout << " FIRE!!\n";
}
The problem is, this code waits 10 seconds and then prints all of the output, instead of counting down from 10. How come this is? And how can I fix it?
(By the way, I tried this on a computer running Linux Mint 17 and MacOSX 10.9, and both times I got the same result)
Probably because you don't flush the output. Try this
cout << x << "..." << flush;
Stream output can be buffered, which means the results don't always appear immediately. Flushing at least increases the chance that you will see some output immediately.
You need to flush the output each time round the loop, otherwise the runtime system will wait for the buffer to be full or (sometimes) an end of line to be sent.
Also, when using std::chrono::duration<> it is better to use one of the explicitly defined types if possible for readability. In this case you are measuring times in seconds so I used std::chrono::seconds in your example:
#include <iostream>
using namespace std;
#include <chrono>
#include <thread>
void Sleep(int x)
{
// better to use explicit types for duration
// for readability
std::this_thread::sleep_for(std::chrono::seconds(x));
}
int main()
{
for(int x = 10; x > 0; x--) {
cout << x << "..." << std::flush; // need to flush here
Sleep(1);
}
cout << " FIRE!!\n";
}
Take the following program:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char a[8] = "Hello, ";
char b[7] = "world!";
strcat(a, b);
cout << a;
return 0;
}
Notice that a and b have the same size as their assigned strings.
The documentation states that for strcat(a, b) to work, a needs to be large enough to contain the concatenated resulting string.
Nevertheless, cout << a displays "Hello, world!". Am I entering undefined behavior?
"Am I entering undefined behavior?"
Yes. A region at the end of a[] has been written over. It worked, this time, but might have belonged to something else.
Here I use a struct to control memory layout, and demonstrate it:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
struct S {
char a[8];
char b[5];
char c[7];
};
S s;
strcpy( s.a , "Hello, " );
strcpy( s.b , "Foo!" );
strcpy( s.c , "world!" );
strcat(s.a, s.c);
cout << s.a << endl;
cout << s.b << endl;
cin.get();
return 0;
}
This outputs:
Hello, world!
orld!
Instead of:
Hello, world!
Foo!
The strcat() has stomped all over b[].
Please note that in a real life example such bugs may be far more subtle, and lead you to wondering why perfectly innocent function calls 250 lines later crash and burn horribly. ;-)
EDIT: May I also recommend that you use strcat_s, instead? Or, even better, std::strings:
#include <string>
#include <iostream>
using namespace std;
int main()
{
string a = "Hello, ";
string b = "world!";
a = a + b;
cout << a;
}
Am I entering undefined behavior?
Yes.
If the documentation says "a needs to be large enough to contain the concatenated resulting string", why don't you simply believe it? What is there to doubt?
In your program, array a is not large enough to contain the result. Therefore, your code is wrong and should be fixed. In the words of the standard, you are indeed entering undefined behavior, which means it may work or it may not...
strcat does what is says on the tin viz. copies b onto the end of a without any care as to what data is already there. Since both variables are on the stack one after the other things work. But try
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char a[8] = "Hello, ";
int i = 10;
char b[7] = "world!";
strcat(a, b);
cout << a << i;
return 0;
}
And you will probably get an unexpected result since your stack has been corrupted by strcat
That is correct.... The behavior is undefined. Just because you got that answer does not mean that it will not crash next time since the array a is too small.