Parsing array in library constructor - Pointer problem (C++) - c++

I am trying to develop an Arduino library that consists out of two classes. I want 'WayPointStack' to store an array of 'WPCommand', but I can't get it to work.
It is obviously a pointer problem, but I don't know how to solve it. There are four errors left in my code:
WayPointStack.cpp:23:7: error: incompatible types in assignment of 'WPCommand*' to 'WPCommand [0]'
_wp = new WPCommand[arrSize]; //Fixed
WayPointStack.cpp:44:34: error: could not convert '(operator new(16u), (((WPCommand*)<anonymous>)->WPCommand::WPCommand(4, 10000), ((WPCommand*)<anonymous>)))' from 'WPCommand*' to 'WPCommand'
return new WPCommand(_END, 10000);
WayPointStack.cpp:59:15: error: no match for 'operator=' (operand types are 'WPCommand' and 'WPCommand*')
_wp[pointer] = new WPCommand(target, time); # Fixed
WPCommand.h:10:7: note: candidate: WPCommand& WPCommand::operator=(const WPCommand&)
class WPCommand # Does not appear anymore, fixed
WPCommand.h
#ifndef WPCommand_h
#define WPCommand_h
#include "Arduino.h"
class WPCommand
{
public:
WPCommand(int target, int time );
WPCommand();
int GetTarget();
int GetTime();
int LEFT;
int RIGHT;
int FORWARD;
int BACKWARD;
int STOP;
int END;
private:
int _target;
int _time;
};
#endif
WayPointStack.h
#ifndef WayPointStack_h
#define WayPointStack_h
#include "Arduino.h"
#include "WPCommand.h"
class WayPointStack
{
public:
WayPointStack();
WayPointStack(WPCommand wp[], int length);
WPCommand GetNextWP();
WPCommand GetWP(int i);
void AddWP(int target, int time);
int SetWPPointer(int i);
int GetWPPointer();
int GetLength();
private:
WPCommand _wp[];
int pointer;
int _length;
};
#endif
WayPointStack.cpp (partly)
#include "Arduino.h"
#include "WayPointStack.h"
#include "WPCommand.h"
#define _BACKWARD 0
#define _FORWARD 1
#define _STOP 2
#define _LEFT 3
#define _RIGHT 4
#define _END 4
#define arrSize 100
WayPointStack::WayPointStack()
{
_wp = new WPCommand[arrSize];
_length = 0;
pointer = 0;
}
WayPointStack::WayPointStack(WPCommand wp[], int length)
{
_wp = new WPCommand[arrSize];
for (int i = 0; i < length; i++){
_wp[i] = wp[i];
}
_length = length;
pointer = 0;
}
WPCommand WayPointStack::GetNextWP()
{
if (pointer < _length){
pointer++;
return _wp[pointer-1];
}
return new WPCommand(_END, 10000);
}
I tried to more or less randomly reference and derefence _wp and wp[] but it did not work.
Edit:
Changing
WPCommand _wp[];
to
WPCommand *_wp;
successfully fixed the first error. Doing the same to
WayPointStack(WPCommand *wp, int length);
Edit:
_wp[pointer] = WPCommand(target, time);
instead of
_wp[pointer] = new WPCommand(target, time);
successfully fixed error number 3.
Edit:
return WPCommand(_END, 10000);
fixed error number 2.
Problem solved.

Related

Overloading [] operator c++

I am trying to overload the indexing operator for a c++ class but I am not able to do so. When I try to index my Matrix class, I get the following error:
error: cannot convert 'Matrix' to 'double*' in initialization
This error occurs on the 9th line of my main.cpp. Does it seem that the indexing does not seem to be recognized by the compiler?
Below is my code:
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <iostream>
using namespace std;
class Matrix
{
public:
/** Default constructor */
Matrix(unsigned int num_cols, unsigned int num_rows);
/** Default destructor */
virtual ~Matrix();
/** Access num_cols
* \return The current value of num_cols
*/
unsigned int getCols() { return _num_cols; }
/** Access num_rows
* \return The current value of num_rows
*/
unsigned int getRows() { return _num_rows; }
double operator[](unsigned int index);
protected:
private:
unsigned int _num_cols; //!< Member variable "num_cols"
unsigned int _num_rows; //!< Member variable "num_rows"
double ** _base;
};
#endif // MATRIX_H
Matrix.cpp
#include "Matrix.h"
Matrix::Matrix(unsigned int num_cols, unsigned int num_rows){
_num_cols = num_cols;
_num_rows = num_rows;
if(_num_cols > 0) {
_base = new double*[_num_cols];
for(unsigned int i = 0; i < _num_cols; i++) {
_base[i] = arr;
cout << _base[i] << endl;
}
}
}
double* Matrix::operator[](int index) {
if (index >= _num_cols) {
cout << "Array index out of bound, exiting";
exit(0);
}
return _base[index];
}
Matrix::~Matrix()
{
//dtor
}
main.cpp
#include <iostream>
#include "Matrix.h"
using namespace std;
int main()
{
Matrix * m = new Matrix(1,2);
double * d = m[1];
delete m;
return 0;
}
The declaration of the overloaded operator member function doesn't match the definition.
You defined the operator as:
double* Matrix::operator[](int index) {
But declared it as:
double operator[](unsigned int index);
The declaration should be:
double *operator[](int index);
Also, the problem with this line:
double * d = m[1];
Is that m is a pointer to a Matrix and the [] operator works on the class instance, not a pointer to it, so you need to dereference m:
double * d = (*m)[1];
Or you can define m as an instance of a Matrix:
Matrix m(1,2);
double * d = m[1];

How to fix Segmentation Fault error when instantiating objects

I'm working to create a few classes that work together to simulate functions for a rental car agency. I have the classes working and I can create objects of each of the classes, but when I try to run the following code I get a segmentation fault and I'm not sure why. Why am I getting a segmentation fault when I declare the objects in this order?
I've tried switching the order in which I declare the objects and the error goes away. If I declare two cars with just the Car() constructor, then the problem also goes away. If I remove any of the functions in either the Car or Sensor class, the error goes away.
PS: I asked this question a few days ago, and I included way too much code because I couldn't identify the error (far from complete, minimal, and verifiable), but this time I've narrowed it down as far as I can. I apologize if it's a lot of code, but I've removed all the code I can and if I remove any more of it the problem goes away.
Here's my main file:
#include "Car.h"
int main() {
char make[] = "Subaru", model[] = "Outback", name[] = "Brandon",
type[] = "radar";
Sensor sensors[3];
Sensor sensor1 = Sensor(type), sensor2 = Sensor(), sensor3 =
Sensor();
sensors[0] = sensor1;
sensors[1] = sensor2;
sensors[2]= sensor3;
Car car1 = Car();
Car car2 = Car(make, 155.81, sensors);
return 0;
}
My Car class:
#ifndef CAR_H
#define CAR_H
#include <iostream>
#include "MyString.h"
#include "Sensor.h"
using namespace std;
#define MAX_STR_SIZE 256
#define MAX_NUM_SNSRS 3
class Car {
public:
Car();
Car(char* make, float baseprice, Sensor* sensors);
void setMake(char* make);
void setBaseprice(float baseprice);
void setAvailable(bool available);
void setOwner(char* owner);
void updatePrice();
private:
char m_make[MAX_STR_SIZE];
Sensor m_sensors[MAX_NUM_SNSRS];
int m_numsensors;
float m_baseprice;
float m_finalprice;
bool m_available;
char m_owner[MAX_STR_SIZE];
};
#endif
#include "Car.h"
Car::Car() {
char dflt[] = {'\0'};
setMake(dflt);
setAvailable(true);
setOwner(dflt);
m_numsensors = 0;
setBaseprice(0.0);
}
Car::Car(char* make, float baseprice, Sensor* sensors) {
char dflt[] = {'\0'};
setMake(make);
setAvailable(true);
setOwner(dflt);
for(int i = 0; i < MAX_NUM_SNSRS; i++) {
(*(m_sensors + i)) = Sensor(*(sensors + i));
if(myStringCompare((sensors + i)->getType(), "none") != 0) {
m_numsensors++;
}
}
setBaseprice(baseprice);
}
void Car::setMake(char* make) {
myStringCopy(m_make, make);
}
void Car::setBaseprice(float baseprice) {
m_baseprice = baseprice;
updatePrice();
}
void Car::setAvailable(bool available) {
m_available = available;
}
void Car::setOwner(char* owner) {
myStringCopy(m_owner, owner);
}
void Car::updatePrice() {
float totSnsrPrice = 0.0;
for(int i = 0; i < m_numsensors; i++) {
totSnsrPrice += (m_sensors + i)->getCost();
}
m_finalprice = m_baseprice + totSnsrPrice;
}
My Sensor class:
#ifndef SENSOR_H
#define SENSOR_H
#include "MyString.h"
#define MAX_STR_SIZE 256
#define NUM_TYPES 5
class Sensor {
public:
Sensor();
Sensor(char* type);
char* getType();
float getCost();
void setType(char* type);
void setCost(float extraCost);
private:
char m_type[MAX_STR_SIZE];
float m_extracost;
};
#endif
#include "Sensor.h"
const char* validSensors[] = {"gps", "camera", "lidar", "radar",
"none"};
const float prices[] = {5.0, 10.0, 15.0, 20.0, 0.0};
Sensor::Sensor() {
char dflt[] = "none";
setType(dflt);
setCost(0.0);
}
Sensor::Sensor(char* type) {
int index = -1;
char dflt[] = "none";
for(int i = 0; i < NUM_TYPES; i++) {
if(myStringCompare(type, *(validSensors + i)) == 0) {
index = i;
}
}
if(index < 0) {
setType(dflt);
setCost(0.0);
} else {
setType(type);
setCost(*(prices + index));
}
}
char* Sensor::getType() {
return m_type;
}
float Sensor::getCost() {
return m_extracost;
}
void Sensor::setType(char* type) {
myStringCopy(m_type, type);
}
void Sensor::setCost(float extracost) {
m_extracost = extracost;
}
myStringCopy and myStringCompare are just the typical std::string copy and compare functions, we're just not allowed to use them (they are include in MyString.h, I've been using them for a while, so I know they work as intended).
I expect the output to be nothing, but still successful, instead of a segmentation fault. I cannot find the error anywhere, any help would be appreciated. Thanks!
Edit: Here's my string class, as asked:
#ifndef MYSTRING_H
#define MYSTRING_H
int myStringCompare(const char* str1, const char* str2);
char* myStringCopy(char* destination, const char* source);
#endif
#include "MyString.h"
int myStringCompare(const char* str1, const char* str2) {
int index = 0;
while(*(str1 + index) != '\0' || *(str2 + index) != '\0') {
if(*(str1 + index) < *(str2 + index)) {
return -1;
}
if(*(str1 + index) > *(str2 + index)) {
return 1;
}
index++;
}
return 0;
}
char* myStringCopy(char* destination, const char* source) {
int index = 0;
while(*(source + index) != '\0') {
*(destination + index) = *(source + index);
index++;
}
*(destination + index) = '\0';
return destination;
}
We don't have the full details on your string class, so this is hard to reproduce.
However, when you call sensors[0] = sensor1; you are copying your Sensor, but haven't defined an assignment operator (or copy constructor for that matter).
You also do this in the Car constructor with
(*(m_sensors + i)) = Sensor(*(sensors + i));
Now without the full details of your string class, I can give suggestions that might help.
First, you are doing a lot of copying when you set up the senors.
You can collapse this
Sensor sensors[3];
Sensor sensor1 = Sensor(type), sensor2 = Sensor(), sensor3 =
Sensor();
sensors[0] = sensor1;
sensors[1] = sensor2;
sensors[2]= sensor3;
down to
Sensor sensors[3]={{type}, {}, {}};
This might not solve the problem, but is less to look at.
Next, remove the setters. You can use delegating constructors to tie the two you have together, and avoid these.
This avoids some copies.
Look very carefully at what gets deep or shallow copied.
If you have two char * types,
char * word = "Hello";
char * another_word = word;
the second is a "shallow" copy. You need an equivalent of strcpy to actually make a different ("deep") copy of the string.

Expected unqualified-id before 'int'

I'm trying to make an Arduino library, for a build that I'm going to be using throughout a few sketches, and I haven't been able to figure out why I keep getting this error. Searching on multiple forums, comes up with no working answers. This is my code:
charLCD.h:
#ifndef charLCD
#define charLCD
#include "Arduino.h"
class charLCD
{
public:
charLCD(int pin1,int pin2,int pin3,int pin4,int enable);
void sendChar(unsigned char c);
private:
int _pin1;
int _pin2;
int _pin3;
int _pin4;
int _enable;
};
#endif
charLCD.cpp:
#include "Arduino.h"
#include "charLCD.h"
#include <limits.h>
charLCD::charLCD(int pin1,int pin2,int pin3,int pin4,int enable) {
_pin1 = pin1;
_pin2 = pin2;
_pin3 = pin3;
_pin4 = pin4;
_enable = enable;
}
void sendChar(unsigned char c) {
// Send char to item
}
char* chartobin ( unsigned char c )
{
static char bin[CHAR_BIT + 1] = {0};
int i;
for ( i = CHAR_BIT - 1; i >= 0; i-- )
{
bin[i] = (c % 2) + '0';
c = c/2;
}
return bin;
}
The problem is on the line where I define the constructor in the header.
Because of
#define charLCD
this is what your compiler sees:
class
{
public:
(int pin1,int pin2,int pin3,int pin4,int enable);
void sendChar(unsigned char c);
private:
int _pin1;
int _pin2;
int _pin3;
int _pin4;
int _enable
};
::(int pin1,int pin2,int pin3,int pin4,int enable) {
_pin1 = pin1;
_pin2 = pin2;
_pin3 = pin3;
_pin4 = pin4;
_enable = enable;
}
// ...
Pick a better header guard.
You also need to qualify the definitions of member functions:
void charLCD::sendChar(unsigned char c) {
// Send char to item
}

How to initialize a constant in a class? [duplicate]

This question already has answers here:
How to initialize const member variable in a class?
(11 answers)
Closed 7 years ago.
So I've looked around and nothing I found has helped me so far.
I have the following header file for my class.
#ifndef CONGERA2_H
#define CONGERA2_H
typedef float Element300;
class Stack300
{
public:
Stack300 ();
Stack300 (const int);
Stack300 (Stack300 &old);
~Stack300();
void push300(const Element300);
Element300 pop300();
void viewTB300();
void viewBT300();
private:
const int MAX_STACK;
Element300 * stackArray;
int top;
};
#endif
And I'm trying to initialize MAX_STACK. If I set it equal to something I get a warning, which would normally be fine but I must transfer this code to Linux afterwards and I can't do that because it says that MAX_STACK is undefined in my three constructors. I've also tried defining it in my class functions file in the first constructor but then I get an error saying that MAX_STACK is not defined in the constructor.
Here is the constructors for my class functions if they are needed.
#include <iostream>
#include "congera2.h"
using namespace std;
Stack300::Stack300 (): MAX_STACK(10)
{
stackArray = new float[3];
for (int i = 0; i < 3; i++)
{
stackArray[i] = '\0';
}
top = -1;
return;
}
Stack300::Stack300 (const int size) : MAX_STACK (10)
{
stackArray = new float[MAX_STACK];
for (int i = 0; i < MAX_STACK; i++)
{
stackArray[i] = '\0';
}
top = -1;
return;
}
Stack300::Stack300 (Stack300 &old) : MAX_STACK (10)
{
top = old.top;
int i = 0;
while (top != old.top)
{
stackArray[i] = old.stackArray[i];
i = i + 1;
top = i;
}
}
Error:
class A
{
public:
const int x=8; // error (c++98/03)
};
Fix 1
class A
{
public:
const int x;
A() : x(8) // ok
{ }
};
Fix 2
class A
{
public:
const static int x;
};
const int A::x=8; // ok

Arduino C++ vector of int

I have a class named Model and in ypur .h file I have this:
private:
vector<int> memory(MEMORY_SIZE);
MEMORY_SIZE is a const in a define header with value 10.
when I try compile I'm gettind this error code
Model.h:33: error: ISO C++ forbids declaration of 'vector' with no type
Model.h:33: error: expected ';' before '<' token
I don't know why this, I'm declaring the type of vector...
The complete header code:
/*
* Model.h
*
* Created on: Sep 13, 2012
* Author: ademar
*/
#ifndef MODEL_H_
#define MODEL_H_
#include "Config.h"
#include "Arduino.h"
#include <vector>
class Model {
public:
Model(int pin, char command[]);
Model(int pin, int initialState, char command[]);
bool isChanged(int currentState);
char* getCommand(void);
int getState();
void setRange(int range);
void usesMemory();
private:
int pin;
int state;
int range;
long time;
char* command;
void updateTime();
bool useMemory;
std::vector<int> memory;
};
#endif /* MODEL_H_ */
And the C++ code:
/*
* Model.cpp
*
* Created on: Sep 13, 2012
* Author: ademar
*/
#include "Model.h"
Model::Model(int pin, char command[]) {
*this = Model(pin,0,command);
}
Model::Model(int pin, int initialState, char command[]) {
this->pin = pin;
this->state = initialState;
this->command = command;
this->range = 1;
this->useMemory = false;
this->updateTime();
}
void Model::usesMemory(){
this->useMemory = true;
}
void Model::setRange(int range){
this->range = range;
}
bool Model::isChanged(int currentState) {
if ((currentState >= (this->state + this->range) || currentState <= (this->state - this->range)) && ((this->time+WAIT_CHANGE)<millis())){
this->state = currentState;
updateTime();
return true;
}
return false;
}
char* Model::getCommand(){
return this->command;
}
int Model::getState(){
return this->state;
}
void Model::updateTime(){
this->time = millis();
}
And the error:
In file included from Honda.h:11,
from Honda.cpp:8:
Model.h:33: error: ISO C++ forbids declaration of 'vector' with no type
Model.h:33: error: invalid use of '::'
Model.h:33: error: expected ';' before '<' token
These are my shots that vector is not included or you are missing namespace std::. The compiler explicitly points out that it does not know what vector is.
What is more, you don't initialize fields like this in C++. You have to do it in the constructor:
#include <vector>
#include <iostream>
#define MEMORY_SIZE 10
class Clazz {
std::vector<int> memory;
public:
Clazz() : memory(MEMORY_SIZE){}
int memory_size() {return memory.size();}
};
int main() {
Clazz c;
std::cout << c.memory_size() << std::endl;
return 0;
}