I'm quite new to c++ and netbeans and have quite a problem here and I can't put my finger on what the error might be.
Building is always succesful but I get a RUN FAILED (exit value -1.073.740.940, total time: 2s) error, when running my program. My code:
Arraylist.hpp:
#include <iostream>
namespace hfu {
class Arraylist {
private:
double* members;
int size;
public:
Arraylist(int);
~Arraylist();
Arraylist(const Arraylist&);
double get(int) const;
void set(int, double);
Arraylist& operator=(const Arraylist&);
//float operator[](int);
friend std::ostream& operator<<(std::ostream&, const Arraylist&);
};
}
Arraylist.cpp:
#include "Arraylist.hpp"
#include <exception>
namespace hfu {
Arraylist::Arraylist(int i) : size(i), members(new double[size]) {
for (int i = 0; i < size; i++) {
set(i, 0);
}
}
Arraylist::~Arraylist() {
delete members;
}
Arraylist::Arraylist(const Arraylist& other) : size(other.size), members(new double[other.size]) {
for (int i = 0; i < 5; i++) {
set(i, other.get(i));
}
}
double Arraylist::get(int i) const {
if (i < 0 || i >= size) {
throw (std::exception());
} else {
return members[i];
}
}
void Arraylist::set(int i, double value) {
if (i < 0 || i >= size) {
throw (std::exception());
} else {
members[i] = value;
}
}
Arraylist& Arraylist::operator=(const Arraylist& other) {
size = other.size;
for (int i = 0; i < size; i++) {
set(i, other.get(i));
}
return *this;
}
// float Arraylist::operator [](int index) {
// return members[index];
// }
std::ostream& operator<<(std::ostream& os, const Arraylist& list) {
for (int i = 0; i < list.size; i++) {
os << "[" << list.get(i) << "]";
}
return os;
}
}
main.cpp:
#include "Arraylist.hpp"
int main() {
try {
auto a1 = hfu::Arraylist(10);
std::cout << a1 << std::endl;
auto a2 = hfu::Arraylist(10);
std::cout << a2 << std::endl;
auto a3 = hfu::Arraylist(10);
std::cout << a3 << std::endl;
}
catch (std::exception& e) {
std::cout << e.what() << std::endl;
}
}
I can create 2 objects of Arraylist.... but not more, it will print the first two and then fail.... but when I create shorter lists, say 3 with only size one... it will work... so I think it might be something with the memory... but I'm at a loss. Ideas?
Thanks a lot!
btw: I'm using netbeans 8.2 and mingw g++ 6.1.0
The initialization order of the member variables is defined by the order of their definitions in the class, not by their order in the initializer list. As a matter of fact, your compiler should be giving you "hfu::Arraylist::size will be initialized after" warnings.
So in your case, members gets initialized before size, thus new double[size] is called when size is still garbage. In my case it simply causes std::bad_array_new_length to be thrown. In your case, things go worse and your application crashes.
So the solution is to change
class Arraylist {
private:
double* members;
int size;
to
class Arraylist {
private:
int size;
double* members;
Related
I am working on a sample test in the site: https://www.testdome.com/for-developers/solve-question/9808
I added two destructors for base class and derived class respectively to release the memory allocated by constructors. The first two requirements of this question are solve successfully, but the result give a fail as: Using timed multiple choice test as multiple choice test: Memory limit exceeded
My modified code as given below, I will appreciate if you can help to fix the fail...
#include <iostream>
#include <string>
class MultipleChoiceTest
{
public:
MultipleChoiceTest(int questionsCount)
{
this->questionsCount = questionsCount;
answers = new int[questionsCount];
for (int i = 0; i < questionsCount; i++)
{
answers[i] = -1;
}
}
void setAnswer(int questionIndex, int answer)
{
answers[questionIndex] = answer;
}
int getAnswer(int questionIndex) const
{
return answers[questionIndex];
}
~MultipleChoiceTest()
{
delete answers; // release memory
}
protected:
int questionsCount;
private:
int* answers;
};
class TimedMultipleChoiceTest : public MultipleChoiceTest
{
public:
TimedMultipleChoiceTest(int questionsCount)
: MultipleChoiceTest(questionsCount)
{
times = new int[questionsCount];
for (int i = 0; i < questionsCount; i++)
{
times[i] = 0;
}
}
void setTime(int questionIndex, int time)
{
times[questionIndex] = time;
}
int getTime(int questionIndex) const
{
return times[questionIndex];
}
~TimedMultipleChoiceTest()
{
delete times; // release memory
}
private:
int* times;
};
#ifndef RunTests
void executeTest()
{
MultipleChoiceTest test(5);
for (int i = 0; i < 5; i++)
{
test.setAnswer(i, i);
}
for (int i = 0; i < 5; i++)
{
std::cout << "Question " << i + 1 << ", correct answer: " << test.getAnswer(i) << "\n";
}
}
int main()
{
for (int i = 0; i < 3; i++)
{
std::cout << "Test: " << i + 1 << "\n";
executeTest();
}
}
#endif
you should use delete [] instead of delete to deallocate dynamic arrays.
Also, you don't seem to use the derived class but, nevertheless, the destructor in MultipleChoiceTest should be virtual
In the code shown below, in the function void printExpensiveThanT(..) i'm supposed to print out the destination, distance and the price for the offers which are more expensive than the offer T in the function, sorted in ascending order by the distance value.
I'm not sure what should i use to sort them, i experimented something with vectors but it didn't work out so i deleted it.
Any help would be appreciated.
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
class Transport {
protected:
char destination[100];
int basePrice;
int distance;
public:
Transport() {}
Transport(char *destination, int basePrice, int distance) {
strcpy(this->destination, destination);
this->basePrice = basePrice;
this->distance = distance;
}
virtual ~Transport() {}
virtual int priceTransport() = 0;
friend bool operator<(const Transport &t1, const Transport &t2) {
return t1.distance<t2.distance;
}
int getDistance(){ return distance; }
char *getDestination() { return destination; }
int getPrice() { return basePrice; }
};
class AutomobileTransport : public Transport {
private:
bool ifDriver;
public:
AutomobileTransport() {}
AutomobileTransport(char *destination, int basePrice,int distance, bool ifDriver) : Transport(destination,basePrice,distance) {
this->ifDriver = ifDriver;
}
void setIfDriver(bool ifDriver) {
this->ifDriver = ifDriver;
}
bool getIfDriver() {
return ifDriver;
}
int priceTransport() {
if(ifDriver) {
basePrice+=basePrice*20/100;
}
return basePrice;
}
friend bool operator<(const AutomobileTransport &a1, const AutomobileTransport &a2) {
return a1.distance<a2.distance;
}
};
class VanTransport: public Transport {
private:
int passengers;
public:
VanTransport() {}
VanTransport(char *destination, int basePrice, int distance, int passengers) : Transport(destination, basePrice, distance) {
this->passengers = passengers;
}
void setPassengers(int passengers) {
this->passengers = passengers;
}
int getPassengers() {
return passengers;
}
int priceTransport() {
for(int i = 0; i < passengers; i++) {
basePrice-=200;
}
return basePrice;
}
friend bool operator<(const VanTransport &k1, const VanTransport &k2) {
return k1.distance<k2.distance;
}
};
void printExpensiveThanT(Transport **offers,int n,AutomobileTransport &T) {
Transport *tmp;
for(int i = 0; i <= n; i++){
if(offers[i]->priceTransport() > T.priceTransport())
cout<<offers[i]->getDestination()<<" "<<offers[i]->getDistance()<<" "<<offers[i]->getPrice()<<endl;
}
}
int main() {
char destination[20];
int type,price,distance,passengers;
bool driver;
int n;
cin>>n;
Transport **offers;
offers=new Transport *[n];
for (int i=0; i<n; i++) {
cin>>type>>destination>>price>>distance;
if (type==1) {
cin>>driver;
offers[i]=new AutomobileTransport(destination,price,distance,driver);
} else {
cin>>passengers;
offers[i]=new VanTransport(destination,price,distance,passengers);
}
}
AutomobileTransport at("Ohrid",2000,600,false);
printExpensiveThanT(offers,n,at);
for (int i=0; i<n; i++) delete offers[i];
delete [] offers;
return 0;
}
Since you're dealing with pointers, the easiest thing to do is to use std::vector and std::sort:
#include <vector>
//...
void printExpensiveThanT(Transport **offers, int n, AutomobileTransport &T)
{
std::vector<Transport*> sortedVect;
for (int i = 0; i < n; i++)
{
if (offers[i]->priceTransport() > T.priceTransport())
sortedVect.push_back(offers[i]); // add this item to the vector
}
// sort the vector based on the dereferenced pointers and their respective
// operator <
std::sort(sortedVect.begin(), sortedVect.end(),
[](Transport* left, Transport* right) { return *left < *right; });
// print out the values
for (auto it : sortedVect)
cout << (*it).getDestination() << " " << (*it).getDistance() << " " << (*it).getPrice() << "\n";
}
Also, your original code looped one more than it should (i <= n was wrong).
Edit:
If your compiler doesn't support the C++ 11 syntax, here is an alternate solution:
#include <vector>
//...
bool Sorter(Transport* left, Transport* right)
{ return *left < *right; }
void printExpensiveThanT(Transport **offers, int n, AutomobileTransport &T)
{
std::vector<Transport*> sortedVect;
for (int i = 0; i < n; i++)
{
if (offers[i]->priceTransport() > T.priceTransport())
sortedVect.push_back(offers[i]); // add this item to the vector
}
// sort the vector based on the dereferenced pointers and their respective
// operator <
std::sort(sortedVect.begin(), sortedVect.end(), Sorter);
// print out the values
std::vector<Transport*>::iterator it = sortedVect.begin();
while (it != sortedVect.end())
{
cout << (*it).getDestination() << " " << (*it).getDistance() << " " << (*it).getPrice() << "\n";
++it;
}
}
I'm new to C++, and I'm having significant trouble with creating an array of objects using a pass by pointer and reference. This is not the actual code; it's an example of what the code essentially does.
#include <iostream>
class MyClass
{
public:
MyClass();
static int doStuff(MyClass *&classArray);
void print_number();
private:
int number;
};
MyClass::MyClass()
{
}
int MyClass::doStuff(MyClass *&classArray)
{
int i = 0;
for (i = 0; i < 10; i++) {
*classArray[i].number = i;
}
return i;
}
void MyClass::print_number()
{
std::cout << number << "\n";
}
int main(void)
{
MyClass *test = nullptr;
int p = MyClass::doStuff(test);
std::cout << p << '\n';
for (int i = 0; i < 10; i++) {
test[i].print_number();
}
return 0;
}
When compiled, this gives a segmentation fault.
This is how you do it (don't forget do delete classArray with delete[] at the end of your program or destructor:
new operator has to have default constructor, if you want to use non-default it is easier to create copy constructor, then a temporary object and copy.
#include <iostream>
class MyClass
{
public:
MyClass();
MyClass(int x, int y);
MyClass(MyClass &OldClass);
static int doStuff(MyClass *&classArray, int Size, int x, int y);
void print_number();
private:
int number, x, y;
};
MyClass::MyClass()
{
number = 0;
x = 0;
y = 0;
}
MyClass::MyClass(int x, int y)
{
number = 0;
this->x = x;
this->y = y;
}
MyClass::MyClass(MyClass &OldClass)
{
this->number = OldClass.number;
this->x = OldClass.x;
this->y = OldClass.y;
}
int MyClass::doStuff(MyClass *&classArray, int Size, int x, int y)
{
if (Size > 0)
{
classArray = new MyClass[Size];
for (int i = 0; i < Size; i++)
{
classArray[i] = MyClass(x, y);
classArray[i].number = i;
}
return Size;
}
else
return 0;
}
void MyClass::print_number()
{
std::cout << number << " " << x << " " << y << "\n";
}
int main(void)
{
MyClass *test = nullptr;
int p = MyClass::doStuff(test, 10, 5, 6);
std::cout << p << '\n';
for (int i = 0; i < p; i++) {
test[i].print_number();
}
delete[] test;
std::cin.get();
return 0;
}
It is not working because you need to allocate the array, as the function is trying to access elements of an array which has yet not been initialized to hold that amount of elements. You can do this by
MyClass *test = new MyClass[array_size];
Or
MyClass test[array_size];
Or by using a resizable container such as std::vector, and changing the function parameters accordingly
*classArray[i].number = i;
You called doStuff with a null pointer, so classArray is null and is not an array. Dereferencing a null pointer results in undefined behavior and on most implementations you'll usually get a crash.
You're also dereferencing something that's not a pointer so this code will not even compile. The error I get is:
main.cpp:23:9: error: indirection requires pointer operand ('int' invalid)
*classArray[i].number = i;
^~~~~~~~~~~~~~~~~~~~~
Presumably this is just because, as you say, the code you're showing is not your real code and classArray[i].number corresponds to a pointer in your real code. But I thought I'd point this out anyway, just in case.
Given the context of your code, here's a working example of your code:
#include <iostream>
class MyClass
{
public:
MyClass() {}
static int doStuff(MyClass*& classArray, size_t sz)
{
int i = 0;
for (; i < sz; i++) {
classArray[i].number = i;
}
// not sure what you want here, but this will return sz+1 if sz>0
return i;
}
void print_number()
{
std::cout << this->number << std::endl;
}
private:
int number;
};
int main(void)
{
MyClass* test = new MyClass[10];
int p = MyClass::doStuff(test, 10);
std::cout << p << '\n';
for (int i = 0; i < 10; i++) {
test[i].print_number();
}
delete[] test;
return 0;
}
Though as others have pointed out, you are using C++, while it's a great exercise in understand how to pass pointers and arrays around, you might find the STL and C++stdlib contain a lot of these types of idioms in an 'easier to understand context'.
Here's your code with some C++ STL:
#include <iostream>
#include <vector>
class MyClass
{
public:
MyClass() {}
MyClass(int i) : number(i) {}
static int doStuff(std::vector<MyClass>& classArray, size_t sz)
{
int i = 0;
for (; i < sz; i++) {
classArray.push_back(MyClass(i));
}
// not sure what you want here, but this will return sz+1 if sz>0
return i;
}
void print_number()
{
std::cout << this->number << std::endl;
}
private:
int number;
};
int main(void)
{
std::vector<MyClass> test;
int p = MyClass::doStuff(test, 10);
std::cout << test.size() << '\n';
// can use iterators here if you want
std::vector<MyClass>::iterator itr = test.begin();
for (; itr != test.end(); itr++) {
itr->print_number();
}
return 0;
}
Hope that can help.
I am having a problem with pieces[] at Copy Constructor and Equal Oparator. i am trying to get pieces like code and month_year but it drops me an error saying 'class machine' has no member named 'get'
#include <iostream>
#include <string>
using namespace std;
class machine {
public:
void set_code(string my_code){
code=my_code;
}
void set_month_year(int my_month_year){
month_year=my_month_year;
}
void set_pieces(int *my_pieces){
for(int i=0;i<25;i++)
pieces[i]=my_pieces[i];
}
string get_code(void){
return code;
}
int get_month_year(void){
return month_year;
int get_pieces_i(int i){
return pieces[i];
}
//Default Constructor
machine(){
code.erase();
month_year=0;
for(int i=0;i<25;i++)
pieces[i]=0;
}
//Destructor
~machine(){}
void print_data(void){
cout << "Code= " << code << endl;
cout << "Month Year " << month_year << endl;
}
void print_pieces(void){
for(int i=0;i<25;i++)
cout << pieces[i] << endl;
}
machine(string my_code, int my_month_year,int *my_pieces){
code=my_code;
month_year=my_month_year;
for(int i=0;i<25;i++)
pieces[i]=my_pieces[i];
}
//Copy Constructor
machine (machine& a)
{
code=a.get_code();
month_year=a.get_month_year();
pieces=a.get.pieces_i();
}
//Equal Operator
void operator = (machine & a)
{
code=a.get_code();
month_year=a.get_month_year();
pieces=a.get_pieces_i();
}
// month & year
int get_month(void) {
return month_year/100;
}
int get_year(void) {
return month_year%100;
}
//return 0 & 1
int ckeck_code(void) {
int counter=0;
for (int i=0;i<25;i++) {
if (pieces [i] <10) {
counter=counter+1;
}
if (counter<5)
return 0;
else
return 1;
}
}
private:
string code;
int month_year;
int pieces[25];
};
int main(void){
return 0;
}
Both copy constructor and assignment operator (yes, it's called assignment operator, not equal operator) should have their parameter of type const machine& instead of machine&.
On the get_* functions, they should be declared as constant member functions. That is,
string get_code(void) const {
return code;
}
int get_month_year(void) const {
return month_year;
}
int get_pieces_i(int i) const {
return pieces[i];
}
Furthermore, the copy constructor and assignment operator should handle pieces like:
for (int i = 0; i < 25; ++i)
pieces[i] = a.get_pieces_i(i);
to match the getters' prototype.
I need to implement a dynamic array by myself to use it in a simple memory manager.
struct Block {
int* offset;
bool used;
int size;
Block(int* off=NULL, bool isUsed=false, int sz=0): offset(off), used(isUsed), size(sz) {}
Block(const Block& b): offset(b.offset), used(b.used), size(b.size) {}
};
class BlockList {
Block* first;
int size;
public:
BlockList(): first(NULL), size(0) {}
void PushBack(const Block&);
void DeleteBack();
void PushMiddle(int, const Block&);
void DeleteMiddle(int);
int Size() const { return size; }
void show();
Block& operator[](int);
Block* GetElem(int);
void SetElem(int, const Block&);
~BlockList();
};
I need to overload operator[].
Block& BlockList::operator\[\](int index) {
try {
if (index >= size)
throw out_of_range("index out of range");
else
return (first[sizeof(Block)*index]);
}
catch(exception& e) {
cerr << e.what() << endl;
}
}
void BlockList::PushBack(const Block& b) {
if(!size)
first = new Block(b);
else {
Block* temp = new Block[size + 1];
int i = 0;
for (i = 0; i < size; i++)
temp[sizeof(Block)*i] = this->operator[](i);
delete []first;
temp += sizeof(Block);
temp->offset = b.offset;
temp->size = b.size;
temp->used = b.used;
first = temp;
}
size++;
}
When I use PushBack to push the first element, it works OK, but when it comes to the second, third, ..., the program didn't crash, but it just shows results I didn`t expect to see.
Here is how I get the contents of my array:
void BlockList::show() {
for (int i = 0; i < size; i++) {
Block current(operator[](i));
cout << "off: " << current.offset << " size: " << current.size << endl;
}
}
first is a Block pointer so you only need to pass in index.
Block* first;
...
first[0] //returns the first element
first[1] //returns the second element
In your example you are passing in too high of an index value when indexing first because you're using sizeof inside.
Corrected code:
Block& BlockList::operator[](int index) {
try {
if (index >= size)
throw out_of_range("index out of range");
else
return (first[index]);//<--- fix was here
}
catch(exception& e) {
cerr << e.what() << endl;
}
}
An array knows how big its elements are, so you don't have to do the math with sizeof(Block). Just use i as the index.
On a related note, the C++ FAQ Lite has a great section on operator overloading that covers all kinds of useful stuff.