Greeting Everyone
I'm trying to compile and run a multi-language code in C, C++ and fortran using gcc, g++ & f77 respectively in UNIX. My program consists of two parts, one in C, the other in C++. They interface via a main() writen in C+, while the fortran code can be ignored for this case.
I have been having numerous issues with this, most noticabbly a Segmentation Error thats been occuring as I run the executable. The previous two topics of mine have whittled it down, unfortunatly nothing seems to be solving the problem outright other than completely removing any input/output processes in either half of my program, which just isn't feasible.
Accessing public class memory from C++ using C
Output conflicts between C & C++
I need to locate the reason why I recieve Segmentation Errors when I use input/outputs in both parts of my program. All sources compile, all link successfully and I know that each part (C & C++) works when linked alone with no such Segmentation Errors (with modifications to let them work alone of course). I've included all the code that interfaces between the two parts and performs input/output functions.
Any help would be much appriciated.
Makefile
products: SlowDynamic.exe
SlowDynamic.exe: main.o SA.o mersenne.o CFE.o BCs.o EMatrix.o Numbering.o KMatrix.o Solve.o MA_57.o blas.o MA_57_Depend.o Metis.o
f77 -L/usr/sfw/lib -R/usr/sfw/lib -lgcc_s -lstdc++ -o SlowDynamic.exe main.o \
SA.o mersenne.o CFE.o MA_57.o blas.o MA_57_Depend.o Metis.o\
BCs.o EMatrix.o Numbering.o KMatrix.o Solve.o
main.o: main.cpp
g++ -c -o main.o main.cpp
SA.o: SA.cpp
g++ -c -o SA.o SA.cpp
mersenne.o: mersenne.cpp
g++ -c -o mersenne.o mersenne.cpp
CFE.o: CFE.c
gcc -c -o CFE.o CFE.c
MA_57.o: MA_57.f
f77 -c -o MA_57.o MA_57.f
blas.o: blas.f
f77 -c -o blas.o blas.f
MA_57_Depend.o: MA_57_Depend.f
f77 -c -o MA_57_Depend.o MA_57_Depend.f
Metis.o: Metis.f
f77 -c -o Metis.o Metis.f
BCs.o: BCs.c
gcc -c -o BCs.o BCs.c
EMatrix.o: EMatrix.c
gcc -c -o EMatrix.o EMatrix.c
Numbering.o: Numbering.c
gcc -c -o Numbering.o Numbering.c
KMatrix.o: KMatrix.c
gcc -c -o KMatrix.o KMatrix.c
Solve.o : Solve.c
gcc -c -o Solve.o Solve.c
clean:
rm *.o Main.exe *.gpi
main.ccp
#include <iostream>
#include "SA.h"
using namespace std;
int main()
{
Initial.Initialize();
Parent.SA(Initial.Write);
system ("PAUSE");
return 0;
}
SA.h
#ifndef SA_H
#define SA_H
#include <vector>
class SimAnneal {
std::vector< std::vector<float> > DensityDomain;
float Solid_Ele_Num, Void_Ele_Num;
float Solid, Void;
double Energy;
double Time;
void Metropolis (double, int, int);
void Next_State (double, int);
double Schedule (double, int);
double ObjFunction ();
void Distribute ();
void Mutate ();
void Convert ();
void PrintDomain ();
void WriteResults (double, double, double, double, double);
public:
int x_max, y_max;
...
std::vector<float> DensityArray;
std::vector<float> EnergyArray;
...
void SA (int);
void Initialize ();
};
extern SimAnneal Initial, Parent, Child, Mutation, Best;
#endif
SA.cpp
include <math.h>
#include <iostream>
#include <fstream>
#include <time.h>
#include <vector>
#include "SA.h"
#include "CFE.h"
#include "randomc.h"
using namespace std;
SimAnneal Initial, Parent, Child, Mutation, Best;
...
void SimAnneal::Initialize ()
{
x_max = ReturnX();
y_max = ReturnY();
EnergyArray.resize(x_max*y_max);
DensityArray.resize(x_max*y_max);
...
Energy = ObjFunction();
}
...
void SimAnneal::PrintDomain ()
{
static ofstream OutputFile;
if (!OutputFile.is_open())
{
char FileName [] = "DensityDomain.txt";
OutputFile.open(FileName);
if (!OutputFile)
{
cerr << "Failed to open " << FileName << endl;
exit(EXIT_FAILURE);
}
//cout << "\nGenerating 'DensityDomain.txt'... \n" << endl;
}
for (int y = 0; y < y_max; y++)
{
for (int x = 0; x < x_max; x++)
{
OutputFile << DensityDomain[y][x] << " ";
}
OutputFile << endl;
}
OutputFile.close();
}
void SimAnneal::WriteResults (double i, double T, double x, double y, double z)
{
static ofstream OutputFile;
if (!OutputFile.is_open()) //check is file has been opened
{
char FileName [] = "Results.txt";
OutputFile.open(FileName);
if (!OutputFile)
{
cerr << "Failed to open " << FileName << endl;
exit(EXIT_FAILURE); //abort program
}
//cout << "\nWriting to file in progress... \n" << endl;
OutputFile << "Iterations" << '\t' << "Temperatures" << '\t' << "Sum Strain Energy" << endl; //<< "SwapNum1" << '\t' << "SwapNum2" << '\t' << "Distance" << endl;
OutputFile << endl;
Initial.Time = (int)time(0);
}
OutputFile << i << '\t' << T << '\t' << z << endl; //'\t' << y << '\t' << z << endl;
if (i == N_max || T <= T_abs)
{
Parent.Time = (int)time(0);
OutputFile << endl
<< "Settings: " << endl
<< "Initial Temperature: " << Initial.Temp << endl
<< "Temperature Iterations: " << i << endl
<< "Step Iterations: " << N_step << endl
<< endl
<< "Results: " << endl
<< "Final Temperature: " << Temp << endl
<< "Minimum: " << Energy << endl
<< "Computational Time (s): " << (Parent.Time-Initial.Time) << endl;
OutputFile.close();
}
}
CFE.h
#ifdef __cplusplus
extern "C" {
#endif
int ReturnX ();
int ReturnY ();
void CFE(float density[], float energy[], int Length);
#ifdef __cplusplus
}
#endif
CFE.c
#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 () { Same but returns elemY }
void CFE(float density[], float energy[])
{
// Extensive use of fscanf(), printf() & fprintf()
// and the following:
FILE *outfile;
outfile = fopen("File.txt", "w");
if(outfile == NULL){
}
else{
for(n=0;n<8;n++)
{
for(m=0;m<8;m++)
{
fprintf(outfile,"%f",KE[n][m]);
fprintf(outfile,"\t");
}
fprintf(outfile,"\n");
}
}
fclose(outfile);
}
I'd suggest going through your code with a critical eye, and checking out everything that looks even remotely odd.
I'd do it for you but C++ isn't in my rotation at the moment and I'm tripping on false positives. For example, this caught my eye:
if (!OutputFile.is_open())
{
char FileName [] = "DensityDomain.txt";
OutputFile.open(FileName);
if (!OutputFile)
{
cerr << "Failed to open " << FileName << endl;
exit(EXIT_FAILURE);
}
//cout << "\nGenerating 'DensityDomain.txt'... \n" << endl;
}
Half way down you're testing if OutputFile is null, after already calling is_open() and open() on it. It looked to me as if either 1) OutputFile won't be null or 2) you shouldn't be calling methods on it before you test it. But I was wrong.
See what I mean?
Related
I always arranged my C++ headers and source files this way:
prog.h
#include <iostream>
class Prog
{
public:
Prog(std::string);
~Prog();
void printName();
private:
std::string name;
};
#include "prog.cpp"
prog.cpp
Prog::Prog(std::string n):
name(n)
{
std::cout << "Program \"" << name << "\" started.\n";
}
Prog::~Prog()
{
std::cout << "Program \"" << name << "\" ended.\n";
}
void Prog::printName()
{
std::cout << "Program name is: \"" << name << "\".\n";
}
main.cpp
#include "prog.h"
int main()
{
Prog prog {"MyCalculator"};
prog.printName();
return 0;
}
But I recently discovered that it's common to arrange them this other way:
prog.h
class Prog
{
public:
Prog(std::string);
~Prog();
void printName();
private:
std::string name;
};
prog.cpp
#include <iostream>
#include "prog.h"
Prog::Prog(std::string n):
name(n)
{
std::cout << "Program \"" << name << "\" started.\n";
}
Prog::~Prog()
{
std::cout << "Program \"" << name << "\" ended.\n";
}
void Prog::printName()
{
std::cout << "Program name is: \"" << name << "\".\n";
}
main.cpp
#include <iostream>
#include "prog.h"
int main()
{
Prog prog {"MyCalculator"};
prog.printName();
return 0;
}
I find the first method more convenient, so is there any reason why I should prefer the second method over the first one?
Header files shouldn't include source code.
I think the first method could provoke dependency errors in a complex enough project (for example, using circular dependencies), because don't separate declaration and definition.
The compilation time is faster in the second one, because you can compile each source file separately.
Also, you might find this question useful.
The first version is what the book "Accelerated C++" (ed. 2000) suggests to do when first introducing header files for class declarations.
I suppose the second version can be seen as more elegant because it groups together all #include pre-compiler statements at the beginning of the program.
Here is a small program that incorporates a call to an Intel MKL library function and DLIB's optimization routine find_min_using_approximate_derivatives.
The code runs perfectly when compiled with the intel C++ compiler: icpc using the invocation:
icpc main.cpp -I /Users/Username/Code/dlib-18.16 -DDLIB_USE_BLAS -I$MKLROOT/include -L$MKLROOT/lib/ -lmkl_core -lmkl_intel_thread -lpthread -lm -lmkl_intel_lp64 -DENABLE_DLIB -DDLIB_USE_BLAS
or by disabling the DLIB related portion of the code via:
clang++ main.cpp -I$MKLROOT/include -L$MKLROOT/lib/ -lmkl_core -lmkl_intel_thread -lpthread -lm -lmkl_intel_lp64
C++ code
// #define ENABLE_DLIB
#ifdef ENABLE_DLIB
#include "dlib/optimization.h"
#endif
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include "mkl.h"
using namespace std;
#ifdef ENABLE_DLIB
using namespace dlib;
#endif
template<typename T>
void printArray(T *data, string name, int len){
cout << name << "\n";
for(int i=0;i<len;i++){
cout << data[i] << " ";
}
cout << "\n";
}
#ifdef ENABLE_DLIB
typedef matrix<double,0,1> column_vector;
double rosen (const column_vector& m)
{
const double x = m(0);
const double y = m(1);
return 100.0*pow(y - x*x,2) + pow(1 - x,2);
}
#endif
int main()
{
#ifdef ENABLE_DLIB
column_vector starting_point(2);
starting_point = 4, 8;
find_min_using_approximate_derivatives(bfgs_search_strategy(),
objective_delta_stop_strategy(1e-7),
rosen, starting_point, -1);
cout << "\nBFGS rosen minimum lies at:\n";
cout << "x = " << starting_point(0) << endl;
cout << "y = " << starting_point(1) << endl;
#endif
int len=10;
double *x=new double[len];
double *y=new double[len];
for(int i=0;i<len;i++){
x[i]=(double)std::rand()/RAND_MAX;
y[i]=(double)std::rand()/RAND_MAX;
}
printArray<double>(x, "x", len);
printArray<double>(y, "y", len);
//sum(x)
double x_sum=cblas_dasum(len,x,1);
cout<< "sum(x): "<< x_sum <<"\n";
}
Nevertheless, it fails replacing icpc with clang++ above with multiple errors of the following kind:
Error
In file included from /opt/intel/composer_xe_2015.3.187/mkl/include/mkl.h:48:
/opt/intel/composer_xe_2015.3.187/mkl/include/mkl_cblas.h:584:6: error: conflicting types for 'cblas_cgemm'
void cblas_cgemm(const CBLAS_LAYOUT Layout, const CBLAS_TRANSPOSE TransA,
^
/Users/Username/Code/dlib-18.16/dlib/matrix/matrix_blas_bindings.h:75:18: note: previous declaration is here
void cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
...suggesting a conflict between the cblas_* routines mirrored in MKL. The documentation for DLIB suggests using the DLIB_USE_BLAS preprocessor directive in order for it to link with MKL but evidently it doesn't seem to help using clang++.
How do I make this work?
I am reading this book called "C++ How to Program" from Deitel and I am still a beginner in this. I know Java, so I am trying to get familiar with the C++ syntax and how it works.
My code is the following:
file >> gradebook_interface.h
#include <string>
//#include <unordered_map>
using namespace std;
//specifing interface
class gradebook_interface
{
public:
//constructor
gradebook_interface(string);
void reset_Coursename();
void setCoursename(string);
string getCourseName();
void displayMessage();
void add_to_hashmap(string,int);
private:
//hashmap init
//unordered_map <string, int> course_map;
string courseName;
};
file >> gradebook_interface.cpp
#include <iostream>
//including interface "gradeinterface"
#include "gradebook_interface.h"
using namespace std;
//constructor from interface
gradebook_interface::gradebook_interface(string name)
{
setCoursename(name);
}
void gradebook_interface::setCoursename ( string name )
{
courseName = name;
}
string gradebook_interface::getCourseName()
{
return courseName;
}
void gradebook_interface::displayMessage()
{
cout << "First C++ application\n" << getCourseName() << "!" << endl;
}
//interfac's methods
void gradebook_interface::reset_Coursename()
{
courseName = "null";
cout << "The course name has been reseted! Value is: " << getCourseName() << endl;
}
void gradebook_interface::add_to_hashmap(string, int)
{
//course_map["test_course"] = 14;
//cout << "Hashmap value just entered:" << endl;
//cout << course_map["test_course"] << endl;
}
file >> gradebook_main.cpp
#include <iostream>
#include "gradebook_interface.h"
using namespace std;
int main()
{
gradebook_interface gradebook_1 ("Maths");
gradebook_interface gradebook_2 ("Greek");
cout << "gradebook 1 " << gradebook_1.getCourseName() << endl;
cout << "gradebook 2 " << gradebook_2.getCourseName() << endl;
};
The book uses Visual Studio that I can't use because I am on ubuntu.
I read somewhere that if you compile C++ code using "gcc" it invokes automatically "g++".
But I get an error, so I am forced to use g++.
My first question is, can I use gcc (any parameters needed?)?
My second question is, how does the linker works?
My third question is why do I get a segmentation fault when I try to run this ??
thanks
I have no problem compiling your program in this way:
g++ -O2 -g main.cpp gradebook_interface.cpp -o main
In fact I used the following Makefile
all: main
main: main.cpp gradebook_interface.cpp
g++ -O2 -g $^ -o $#
and simple issued make && ./main outputting:
gradebook 1 Maths
gradebook 2 Greek
I ran it under valgrind; so far no detected memory errors. I haven't looked at your code
Edit On the How does the linker work part:
If you rewrote that Makefile like so:
all: main
CPPFLAGS+=-O2 -g
main: main.o gradebook_interface.o
g++ $(CPPFLAGS) $^ -o $#
It would result in the following build steps:
g++ -O2 -g -c -o main.o main.cpp
g++ -O2 -g -c -o gradebook_interface.o gradebook_interface.cpp
g++ -O2 -g main.o gradebook_interface.o -o main
which shows how to do the compile steps (-c) separately from the link step. The link step could in that case be written as the explicit call to ld intead, but you'll have to specify the runtime libraries for libgcc and libstdc++ yourself
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why can templates only be implemented in the header file?
Here's my make file:
#!/usr/bin/make -f
compiler = g++
compiler_flags = -Wall -I /usr/include/c++/4.5
debug_flags = -D DEBUG -g
binary_filename = sort_testing.bin
all: clean release
release:
$(compiler) $(compiler_flags) main.cpp sort.o -o $(binary_filename)
debug: sort.o
$(compiler) $(debug_flags) $(compiler_flags) main.cpp sort.o -o $(binary_filename)
run:
./$(binary_filename)
clean:
rm -f *.o $(binary_filename)
sort.o:
$(compiler) $(debug_flags) $(compiler_flags) -c sort.cpp
Here are my C++ Files:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T> void swap(T*,int,int);
}
#endif
// sort.cpp
#include "sort.hpp"
namespace sort{
template<class T>
void swap(T* items, int index_a, int index_b){
T t = items[index_a];
items[index_a] = items[index_b];
items[index_b] = t;
}
}
// main.cpp
#include <iostream>
#include <exception>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#include "sort.hpp"
using namespace sort;
#define NUM_INTS 5
int main(int argc, char** argv){
try{
cout << "\n\n\n";
srand(time(NULL));
int * int_coll = new int[NUM_INTS];
for (int x = 0; x < NUM_INTS; x++)
int_coll[x] = rand() % 100 + 1;
cout << "Before swap" << endl;
for (int x = 0; x < NUM_INTS; x++)
cout << "int " << x << " == " << int_coll[x] << endl;
cout << "\n\n\n";
cout << "Swapping ints" << endl;
swap<int>(int_coll, 0, 1);
cout << "AFter swap" << endl;
for (int x = 0; x < NUM_INTS; x++)
cout << "int " << x << " == " << int_coll[x] << endl;
}catch(exception& e){
cout << "Exception: " << e.what() << endl;
}
return 0;
}
And, here's my problem:
./make clean debug
rm -f *.o sort_testing.bin
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 -c sort.cpp
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 main.cpp sort.o -o sort_testing.bin
/tmp/ccRl2ZvH.o: In function `main':
/home/dev/c++/sorting/main.cpp:33: undefined reference to `void sort::swap<int>;(int*, int, int)'
collect2: ld returned 1 exit status
make: *** [debug] Error 1
Any idea how to resolve this issue?
Template definitions need to either be visible at the point of use (so that they can be implicitly instantiated) OR you need to explicitly instantiate them (in this case the linker will bring the explicit instantiation and the usage together).
In your situation I would go with option one (and implicit instantiation). This means you need to move the template definition (of the template) into the header file:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T>
void swap(T*,int,int)
{
T t = items[index_a];
items[index_a] = items[index_b];
items[index_b] = t;
}
}
#endif
Alternatively (but less useful in the general case (but has its uses)) is explicit template instantiation. Here you define in sort.cpp which variants of the template you want to have defined.
// sort.cpp
#include "sort.hpp"
namespace sort{
template<class T>
void swap(T* items, int index_a, int index_b){
T t = items[index_a];
items[index_a] = items[index_b];
items[index_b] = t;
}
// Define an explicit function template instantiation.
// Here we define that the integer version of the template must exist.
template void swap<int>(int*,int,int);
}
This is useful when you want to limit the number of versions of a template are available.
Template definitions must be in the same file. So define the function in the header file itself.
Or include the .cpp file in the header at the bottom as:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T> void swap(T*,int,int);
}
#include "sort.cpp" //<--------------- this!
#endif
You can not define templates in a .cpp file. The definition of swap should be in the sort.hpp file only. See this FAQ Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file? for more details.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Float to binary in C++
I want to print out the binary representation of a float number in C++. Not very practical, just out of curiosity.
The following program doesn't compile though. The reinterpret_cast fails. What kind of cast can I use so that I can do the " &(1 << i) " part?
#include <iostream>
using namespace std;
void toBinary(float num) {
int numi = reinterpret_cast<int>(num);
cout << num << " " << numi << endl;
for (int i = 0; i < 8 * sizeof(num); i++){
if (numi & (1<<i)) {
cout << 1;
} else {
cout << 0;
}
}
cout << endl << endl;
}
int main() {
float a;
cout << sizeof(int) << " " << sizeof(float) << endl;
a = 13.5;
toBinary(a);
toBinary(13.9);
toBinary(2 * a);
toBinary(-a);
}
There's a much easier way. Take a pointer to the float, and reinterpret_cast it to a pointer to char. Now loop through sizeof(float) and convert each char to 8 binary digits. This method works for doubles too.
Use a union. I did this code to do exactly what you want:
// file floattobinary.cc
#include <string>
#include <inttypes.h> // for uint32_t
using namespace std;
void floatToBinary(float f, string& str)
{
union { float f; uint32_t i; } u;
u.f = f;
str.clear();
for (int i = 0; i < 32; i++)
{
if (u.i % 2) str.push_back('1');
else str.push_back('0');
u.i >>= 1;
}
// Reverse the string since now it's backwards
string temp(str.rbegin(), str.rend());
str = temp;
}
Below is a test program to run this function:
// file test.cc
#include <iostream>
#include <string>
#include <cstdlib> // for atof(3)
using namespace std;
void floatToBinary(float, string&);
int main(int argc, const char* argv[])
{
string str;
float f;
if (argc > 1)
{
f = static_cast<float>(atof(argv[1]));
floatToBinary(f, str);
}
cout << str << endl;
return 0;
}
Compile and run (I'm using GNU g++ on Linux):
me#mypc:~/college/c++/utils$ g++ -c floattobinary.cc
me#mypc:~/college/c++/utils$ g++ -c test.cc
me#mypc:~/college/c++/utils$ g++ -o test *.o
me#mypc:~/college/c++/utils$ ls
floattobinary.cc floattobinary.o test* test.cc test.o
me#mypc:~/college/c++/utils$ ./test 37.73
01000010000101101110101110000101
me#mypc:~/college/c++/utils$ ./test 2.0
01000000000000000000000000000000
me#mypc:~/college/c++/utils$ ./test 0.0
00000000000000000000000000000000
me#mypc:~/college/c++/utils$ ./test 237.74
01000011011011011011110101110001
me#mypc:~/college/c++/utils$ ./test 2.74e12
01010100000111110111110100101111
me#mypc:~/college/c++/utils$ ./test 2.74e13
01010101110001110101110001111010
me#mypc:~/college/c++/utils$ ./test -88.37
11000010101100001011110101110001