I just wrote a program with a Matrix object inside the main.cpp file. Everything was fine.
Now I want to outsource the object into a Matrix.cpp file and Matrix.h header, but I have encountered an error.
I get the following compiler error:
Matrix.cpp:5:15: error: expected id-expression before '(' token
Matrix::Matrix(int n_rows){
Matrix.h:
#ifndef Matrix
#define Matrix
#include "iostream"
#include "string"
#include <sstream>
#include <cstdlib>
using namespace std;
class Matrix{
private:
int n_rows;
int* vect;
public:
Matrix(int);
};
#endif
Matrix.cpp:
#include "Matrix.h"
// Constructor
Matrix::Matrix(int n_rows){ //ERROR
if(n_rows>0){
this->n_rows = n_rows;
this->vect = new int[n_rows];
srand(time(NULL));
for(int i = 0; i< n_rows; i++){
this->vect[i] = rand() % 100;
}
}
}
Maybe there is a keyword to this problem that I do not know jet. I would appreciate it if you could help me out.
NEW: Based on the accepted answer: Why is the the occurence Matrix substituted by a blank space?
#define Matrix means that every occurrence of 'Matrix' will be replaced with nothing by the preprocessor.
Thus, your compiler sees this
using namespace std;
class {
private:
int n_rows;
int* vect;
public:
(int);
};
::(int n_rows){
if(n_rows>0){
this->n_rows = n_rows;
this->vect = new int[n_rows];
srand(time(NULL));
for(int i = 0; i< n_rows; i++){
this->vect[i] = rand() % 100;
}
}
}
But the error message refers to the code before preprocessing, which makes it pretty incomprehensible.
Include guards are conventionally all uppercase (as are macros in general).
You should do that, too.
#ifndef MATRIX_H
#define MATRIX_H
Related
I'm trying to build a class named "Tombola" which should contain as private variable an empty vector. This should be filled at runtime through the class member Tombola.estrai(), which generates a random number and insert it inside the vector named "order" by the method order.push_back(number). This is the class definition in the tombola.h header:
#ifndef TOMBOLA_H
#define TOMBOLA_H
#include <cstdlib>
#include <vector>
using namespace std;
class Tombola {
private:
bool on_off[90];
int tabellone[9][10];
int x_max = 9;
int y_max = 10;
vector<int> order;
public:
Tombola();
~Tombola();
void nuovo();
int estrai();
bool completato();
void stampa();
void stampa_tab();
};
#endif
And this is the implementation of constructor/destructor and Tombola::estrai() inside tombola.cc:
#include "tombola.h"
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <vector>
#include <iostream>
using namespace std;
Tombola::Tombola () {
vector<int> ord;
order = ord;
int z=1;
for(int i=0;i<90;i++) {
on_off[i] = false;
}
for(int j=0;j<=x_max;j++) {
for (int k=0;k<=y_max;k++) {
tabellone[j][k] = z;
z++;
}
}
}
Tombola::~Tombola() {
cout << "Tombola is destroyed" << endl;
}
int Tombola::estrai() {
srand(time(NULL));
int estrazione = int(ceil(rand()/double(RAND_MAX)*90));
on_off[estrazione]==true;
order.push_back(estrazione);
return order.back();
}
and this is the call to the method in the main.cpp file:
#include "tombola.h"
#include <cstdlib>
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
int main () {
Tombola natale;
cout << natale.estrai();
}
When I compile the program everything goes fine, but when I execute the main I get a segmentation fault error which seems to be due to some sort of allocation error when trying to store the item inside the order vector, as reported by the debugger. Could someone explain to me how to solve the error and why the error occours? Thank you.
The reason of segmentation fault is in the constructor. You have to change for(int j=0;j<=x_max;j++) to for(int j=0;j<x_max;j++) in order not to cross the bounds of the array.
for(int j=0;j<x_max;j++) {
for (int k=0;k<y_max;k++) {
tabellone[j][k] = z;
z++;
}
}
However, there are also some minor issues in the code that are worth being mentioned
declaring default-initialized ord vector and assigning it to order is pointless because order is already default-initialized.(See member initializer list for more information).
using namespace std; in a header file is a terrible idea, because if you had a large codebase, and had multiple source files where you want to include that header, everywhere the using statement will be applied, which probably is not desired.
Bad access means that i am trying to access memory that doesn't exists I have tried and tried to allocate memory for this class, but have failed everywhere. I do not know where the error is actual coming from. It only tells me that my setter method is when the program crashes. In the setFName() method is where the error occurs. But in the main method is where it actually occurrs.
nurse.hpp
#ifndef Nurse_hpp
#define Nurse_hpp
#include <stdio.h>
#include <string>
#include <stdlib.h>
using namespace std;
class nurse{
private:
string firstName;
public:
nurse() {
firstName = "jim";
}
string getFName() {return firstName;}
void setFName(string fName) {firstName = fName;} // Thread 1: bad access 0x0
};
#endif /* Nurse_hpp */
here is where the error is actually happening
main.cpp
#include <cstdint> // ::std::uint64_t type
#include <cstddef> // ::std::size_t type
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include "nurseHolder.hpp"
using namespace std;
nurseHolder *l = new nurseHolder();
int main() {
return 0;
}
and finally here is the class that is causing the issue
nurseHolder.hpp
#ifndef Nurses_hpp
#define Nurses_hpp
#include <stdio.h>
#include <vector>
#include <stdlib.h>
#include "Nurse.cpp"
using namespace std;
class nurseHolder{
private:
int nurse_cnt;
int nurse_cap;
vector<nurse> nurse_list;
public:
nurseHolder() {
nurse_cnt = 0;
nurse_cap = 10;
for(int i= 0; i < 11; i++){
nurse_list[i].setFName("na");
}
}
vector<nurse> &getNurseList() { return nurse_list;}
};
#endif /* Nurses_hpp */
I tried to make this compact as possible sorry if its a lot of code.
here is what I changed to make the code work:
nurseHolder() {
nurse_cnt = 0;
nurse_cap = 10;
for(int i= 0; i < 11; i++){
nurse l;
nurse_list.pushback(l);
}
}
Is this a correct way to do this?
Your vector nurse_list has size 0. So you cannot use [] operator to set names.
There are two ways you can correct this:
Set an initial size to the vector and use [] to set names.
Use push_back to add elements to the vector.
First method.
nurse_list.resize(noOfTotalNurses).
nurse_list[i].setFName("name");
Second method.
nurse tNurse; //local nurse object
tNurse.setFName("name");
nurse_list.push_back(tNurse);
I have carefully looked into my code but don't see why this error comes out.
The error message is the following:
main.cc: In function ‘int main()’:
main.cc:12: error: conflicting declaration ‘traj dim’
main.cc:11: error: ‘dim’ has a previous declaration as ‘unsigned int dim’
and one can reproduce it with the following command
g++ -o a.out realvector.cc traj.cc main.cc
My main.cc is
#include "realvector.h"
#include "traj.h"
using namespace std;
int main() {
unsigned int dim=1000;
traj TRAJ(dim);
return 1;
}
traj is defined in traj.h as
#ifndef TRAJ
#define TRAJ
#include "realvector.h"
class traj{
public:
traj(unsigned int);
~traj();
void next(double &);
private:
unsigned int it,nt; // index, total array size
double dt; // step time
RealVector r,v,a;
};
#endif
the constructor is defined in traj.cc
#include "realvector.h"
#include "traj.h"
traj::traj(unsigned int dim) : nt(dim) {
RealVector r(nt),v(nt),a(nt);
it=0;
}
traj::~traj(){
r.~RealVector();
}
Any idea why this error comes out? Also, is the way to define r,v,a correct? RealVector is a home-defined class with its constructors defined as the following
#include "realvector.h"
using namespace std;
RealVector::RealVector() {}
RealVector::RealVector(unsigned int n)
: dim(n) {
data = new double[dim];
for (int i=0; i<dim; i++)
data[i]=0;
}
RealVector::~RealVector(){
delete[] data;
}
with realvector.h as
#ifndef REAL_VECTOR_H
#define REAL_VECTOR_H
#include <iostream>
class RealVector {
public:
RealVector();
RealVector(unsigned int n);
~RealVector();
int dim;
double* data;
};
#endif
The code is not complete... as a wild guess you also have a TRAJ macro that makes reading what the code really is impossible.
In traj.h you have
#define TRAJ
which defines TRAJ as an empty "string" and this leads to this replace by the preprocessor:
traj TRAJ(dim);
to
traj (dim);
which produces the error message.
I guess you should rename TRAJ in the include file to TRAJ_H and then it works.
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
I have the main.cpp, a class Student and a global.h library.
I want the functions of global.h to be acessible everywhere, so I did this.
global.h
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
using namespace std;
#ifndef GLOBAL_H
#define GLOBAL_H
int min(vector<int> v) {
int min = -99999999;
for (unsigned int i = 0; i < v.size(); i++) {
if (v[i] > min) min = v[i];
}
return min;
}
double average(vector<int> v) {
int sum = 0;
for (unsigned int i = 0; i < v.size(); i++) {
sum += v[i];
}
return (double)sum / v.size();
}
#endif /* GLOBAL_H */
Student.h
#include "global.h"
#ifndef STUDENT_H
#define STUDENT_H
class Student {
private:
string name;
vector<int> grades;
public:
Student();
void setName(string name);
void addGrade(int grade);
int getBestGrade();
double getAverageGrade();
};
#endif /* STUDENT_H */
Student.cpp
#include "Student.h"
Student::Student() {
}
void Student::setName(string name) {
this->name = name;
}
void Student::addGrade(int grade) {
this->grades.push_back(grade);
}
int Student::getBestGrade() {
return min(this->grades);
}
double Student::getAverageGrade() {
return average(this->grades);
}
main.cpp
#include "Student.h"
using namespace std;
int main(int argc, char** argv) {
Student a;
a.setName("John");
a.addGrade(15);
a.addGrade(13);
a.addGrade(20);
cout << a.getAverageGrade() << endl;
cout << a.getBestGrade() << endl;
return 0;
}
I get this error:
multiple definition of min(...)
multiple definition of average(...)
It seems I am including "global.h" multiple times. But I don't know where. Indeed, I use include "Student.h" two times. But I think the class won't work if I don't to it like this.
Please, help me find out how to include a global library inside a class.
Thanks
##############################
SOLUTION
Thanks to WhiteViking, I have now a solution.
The global.h must have a global.cpp.
global.h
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
using namespace std;
#ifndef GLOBAL_H
#define GLOBAL_H
int min(vector<int> v);
double average(vector<int> v);
#endif /* GLOBAL_H */
global.cpp
#include "global.h"
int min(vector<int> v) {
int min = -99999999;
for (unsigned int i = 0; i < v.size(); i++) {
if (v[i] > min) min = v[i];
}
return min;
}
double average(vector<int> v) {
int sum = 0;
for (unsigned int i = 0; i < v.size(); i++) {
sum += v[i];
}
return (double)sum / v.size();
}
Your question does not show this in detail, but it seems you are defining funcX and funcY in global.h instead of just declaring them.
The preprocessor will replace all #include statements with the verbatim contents of those include files. This happens recursively. So after preprocessing, the compiler sees a "A.cpp" that includes the contents of global.h with the full definitions of funcX and funcY. (global.h was included indirectly via A.h. ) The same thing happens for Main.cpp.
After compilation, the object files for A.cpp as well as for Main.cpp will contain the compiled definitions of funcX and funcY. The error then happens when these object files are linked together in order to build the final executable. The linker will see multiple definitions of these functions and will error out. (It doesn't know/check/care if these definitions are actually identical.)
The solution is to only declare these functions in global.h and put their definition in a separate .cpp file, say global.cpp. For example:
In global.h:
// declarations only here
int funcX(int x);
int funcY(int x);
In global.cpp:
int funcX(int x)
{
return 2 * x;
}
int funcY(int x)
{
return x + 42;
}
In short: you were violating the so-called One Definition Rule (ODR).
I have a card class in which I initialize a vector:
#ifndef CARD_H
#define CARD_H
#include <vector>
using namespace std;
class Card
{
private:
vector<int> CC;
vector<int> iChance;
public:
Card();
void draw_Card();
};
#endif
And in my .cpp file I have
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iterator>
#include "card.h"
using namespace std;
Card::Card()
{
srand(time(NULL));
vector<bool> drawn(20);
for (int i = 0; i < 20; i++)
{
int numvalue = rand()%20 + 1;
if (drawn[numvalue - 1])
{
i--;
continue;
}
else
{
drawn[numvalue - 1] = true;
CC.push_back(numvalue);
iChance.push_back(numvalue);
}
}
copy (CC.begin(), CC.end(), ostream_iterator<int>(cout, " "));
}
It is segfaulting when I call the push_back function for CC, which means the vector CC is not being passed in correctly?
If i called the vectors not in the private area and directly inside the constructor it works. Sorry if this maybe a really simple fix, just started learning classes and vectors. Thank you for the help.
Edit: I am almost certain this is the problem. The value of CC and iChance are not getting past into the constructor, so when the program tries to set a value to the variables nothing exists and it seg faults.
Also I noticed that if i instead declared the CC and iChance variable in the cpp file and not the .h file the program would work.
I am just trying to figure out why and how I could fix this