/This program is using template class. I don't know why but this program is throwing an error at run time related memory access violation. in below comments i will explain which line is causing this error./
#include<iostream>
using namespace std;
const int size =3;
template <class t="">
class vector
{
T* v;
public:
vector()
{
v=new T[size];
for(int i=0;i<size;i++)>
v[i]=0;
}
vector(T* a)
{
for(int i=0;i<size;i++)>
v[i]=a[i];
}
T operator*(vector &y)
{
T sum=0;
for(int i=0;i<size;i++)>
sum+=this->v[i] * y.v[i];
return sum;
}
void display(void)
{
for(int i=0;i<size;i++)>
{
cout<<v[i]<<"\t";
}
cout<<"\n";
}
};
int main()
{
int x[3]={1,2,3};
int y[3]={4,5,6};
vector<int> v1;
vector <int> v2;
v1=x; // This is causing an error
v2=y; // This is causing an error
//int R=v1*v2;
//cout<<"R = "<<R<<"\n";
cout<<"V1 = ";
v1.display();
cout<<"V2 = ";
v2.display();
cout<<"V1 x V2 = "<<v1*v2;
return 0;
}
It seems that the problem is in this constructor
vector(T* a)
{
for(int i=0;i<size;i++)>
v[i]=a[i];
}
You did not allocate memory for the array pointed by v.
2 Problems:
You are not initializing memory for your vector
You are calling the constructor incorrecly
To fix #1
vector(T* a)
{
v=new T[size];
for(int i=0;i<size;i++)>
v[i]=a[i];
}
To fix #2
int x[3]={1,2,3};
int y[3]={4,5,6};
vector<int> v1(x);
vector <int> v2(y);
the constructor vector(T * a) will get called and the member v is not initialized with anything. This causes undefined behavior. So to fix this you need to allocate in that constructor
vector(T* a)
{
v = new T[size];//this line is new
for(int i=0;i<size;i++)
v[i]=a[i];
}
My guess is there is no operator=(int []) defined for vector.
So in other words, compiler does not know what do you mean by v1=x when it comes to type int[] = vector<int>.
You are not calling the overloaded constructor there. So you either need to call it vector<int> v1(y); or implement vector::operator=(const T[] v);
I hope i got the types right
When calling the lines in question, the program is using a default assignment operator which is doing something that causes your violation. You need to implement this yourself, for example, this worked for me:
T& operator=(T const * a)
{
for(int i=0;i<size;i++)
v[i]=a[i];
return *this;
}
Related
I'm trying to make a copy constructor with low level arrays and I'm getting a core dumped error when using delete, can't find out a solution because I'm not able to use std::vector to make this.
Can you guys help me ?? =)
#include<iostream>
#include<string>
#include<initializer_list>
class Vector{
size_t n;
double* datos;
public:
Vector(size_t n_,double);
Vector(const std::initializer_list<double>&l);
void show();
~Vector(){
delete[] datos;
}
Vector(Vector&& other):n(other.n){
delete [] datos;
datos =other.datos;
other.datos =nullptr;
}
Vector(const Vector& v);
Vector operator = (const Vector& v);
};
/* --------------------------- METODOS DE LA CLASE -------------------------- */
Vector::Vector(const Vector&v){
delete[]datos; //CORE DUMPED
n=v.n;
datos = new double[n];
for (size_t i = 0; i < n; i++)
{
datos[i] = v.datos[i];
}
std::cout<<std::endl;
}
Vector Vector::operator = (const Vector& v){
delete [] datos;//CORE DUMPED
n = v.n;
for (size_t i = 0; i < n; i++)
{
datos[i] = v.datos[i];
}
return *this;
}
Vector::Vector(const std::initializer_list<double>&l):n(l.size()),datos(new double[n]){
size_t j= 0;
for (auto i:l)
{
datos[j]=i;
++j;
}
}
void Vector::show(){
for (size_t i = 0; i < n; i++)
{
std::cout<<datos[i]<<", ";
}
std::cout<<std::endl;
}
Vector::Vector(size_t n_,double d=0):n(n_),datos(new double[n]){
if (n < 1)
{
throw std::invalid_argument("Wrong size!");
}
for (size_t i = 0; i < n; i++)
{
datos[i] = d;
}
}
int main(){
Vector b={2,3,4,5,6},a(3);
a=b;
a.show();
}
Using POP OS 21.04 (just in case this can help).
Please don't be rough with me I'm a junior programmer trying to pass September's exams =(
Vector::Vector(const Vector&v){
delete[]datos; //CORE DUMPED
You didn't initialise datos, so its value is indeterminate. When you delete an indeterminate pointer, then the behaviour of the program is undefined. "CORE DUMPED" is one possible behaviour that you may observe.
You are issuing unneeded calls to delete [] datos in your constructors (move and copy).
Since datos is uninitialized, calling delete [] on an uninitialized pointer leads to undefined behavior -- in your case, your program crashes.
Since the objects are being constructed, there is no reason to issue a delete [] on the pointer, since the object this is brand new.
Simply remove the call to delete [] datos; from the constructors. Whether this is the only problem is another story, but it is an existing one.
In addition, your assignment operator:
Vector Vector::operator = (const Vector& v)
is also incorrect. It fails to allocate new memory after the delete [] call, thus the for loop that is written will write into unallocated memory. Also, it should return a reference to the current Vector object, not a brand new Vector object.
The easiest way to implement the assignment operator is to use std::swap:
#include <algorithm>
//...
Vector& Vector::operator = (Vector v)
{
std::swap(v.datos, datos);
std::swap(v.n, n);
return *this;
}
This assumes you have a working, non-buggy copy constructor and destructor for Vector. See the copy / swap idiom for details on why this works.
I'm new with c++ and I've been meaning to implement vector calculations via operator overloading.
The code that's not functioning as I intended is this.
First, main.cpp
#include <iostream>
#include "MyVector.h"
#include "MyVector.cpp"
int main() {
double forvector1[] = {0.1,0.2,0.3};
double forvector2[] = {0.2,0.3,0.5};
MyVector vector1(forvector1,3);
MyVector vector2(forvector2,3);
MyVector temp = vector1 + vector2;
temp.print();
return 0;
}
Then, MyVector.cpp
#include "MyVector.h"
#include <iostream>
using namespace std;
MyVector::MyVector(double numList[], int size) : numList(numList), size(size) {
}
MyVector::MyVector(){ //empty vector;
}
void MyVector::print(){
cout<<"("<<numList[0];
for(int i=1;i<size;i++){
cout<<", "<<numList[i];
}
cout<<")"<<endl;
}
MyVector MyVector:: operator+(MyVector vec){
if(vec.size != size){
cout<<"+ cannot be applied to ";
cout<<"("<<numList[0];
for(int i=1;i<size;i++){
cout<<", "<<numList[i];
}
cout<<") and ";
vec.print();
return MyVector();
}
double tempList[size];
for(int i=0;i<size;i++)
{
tempList[i]=numList[i]+vec.numList[i];
}
MyVector result(tempList,size);
return result;
}
Finally, this is my MyVector.h
class MyVector{
private:
int size;
double * numList;
public:
MyVector(double numList[], int size); //size>=1
MyVector(); //empty Vector
void print(); //print its content e.g. (1, 2, 3, 4)
MyVector operator-(MyVector vec);
MyVector operator+(MyVector vec);
double operator*(MyVector vec);
MyVector operator/(MyVector vec);
//You may add more member functions as well
};
#endif // MYVECTOR_H_INCLUDED
According to the main.cpp, I should be getting (0.3, 0.5, 0.8) for the output. However, I keep getting (0.3, 0, 2.12199e-314), which means probably only the first element of the result array was right. I'm guessing it's because of the pointer I used to point at the array, so that's why only the first element was correct. Is there any way I could make the operator+ work? Any help would be appreciated. Thanks!
My guess would be that there is a dangling pointer.
double tempList[size];
for(int i=0;i<size;i++)
{
tempList[i]=numList[i]+vec.numList[i];
}
MyVector result(tempList,size);
return result;
tempList points to data that are local to the function, but result uses it. In your constructor, you should copy the data in the array into another array owned by the object.
I am new c++ programmer. I want to create a Matrix class in c++ using dynamic programming. I had a problem with copy constructor. When I call operator + to use it for matrix-addition, the copy constructor throws a bad_alloc-Exception. The problem occurs in the copy-constructor, when i try to create a new dynamic memory, where i can copy my data:
matrix= new int [size];
I don 't understand why.
Here is the whole code: (only the cpp-file)
#include <iostream>
#include "Matrix.hpp"
Matrix::Matrix(int m, int n){
mat_row=m;
mat_col=n;
matrix = new int[mat_row*mat_col];
//initialization
for(int i=0;i<mat_row*mat_col;i++){
matrix[i]=0;
}
}
//copy-Constructor
Matrix::Matrix(const Matrix& mat){
int size=mat_row*mat_col;
matrix= new int [size];
for(int i=0;i<size;i++){
matrix[i]=mat.matrix[i];
}
}
Matrix::~Matrix(){
if(matrix){
delete [] matrix;
}
}
//assigment operator
Matrix& Matrix::operator=(const Matrix& mat){
std::cout<<"assignment-operator is used"<<std::endl;
if(this!=&mat){
int size=mat_row*mat_col;
for(int i=0;i<size;i++){
matrix[i]=mat.matrix[i];
}
}
return *this;
}
void Matrix::set(int m, int n, double value){
if(matrix){
matrix[m*mat_col+n]=value;
}
}
double Matrix::get(int m, int n){
return matrix[m*mat_col+n];
}
Matrix Matrix::operator+(Matrix mat){
/*
Matrix resultMatrix(mat_row, mat_col);
for(int i=0;i<mat_row;i++){
for( int j=0;j<mat_col;j++){
resultMatrix->set(i,j,this->get(i,j)+mat.get(i,j));
}
}
return *this;
*/
}
int main(){
Matrix mat1(3,3);
mat1.set(0,0,11);
mat1.set(1,1,22);
mat1.set(2,2,33);
mat1.print();
std::cout<<std::endl;
Matrix mat2(3,3);
mat2=mat1;
mat2.print();
std::cout<<std::endl;
mat2.set(0,1,55);
mat2.set(1,1,110);
mat2.set(2,2,220);
mat2.print();
mat1+mat2; //the problem occurs when this row will be executed
}
The first thing I noticed is that in your copy constructor mat_row and mat_col are not initialized. They should be getting set from the values that are in the object you are copying before you multiply them together to make size. If you don't do that first then the existing values are undefined and likely very large values, causing the new to fail.
//copy-Constructor
Matrix::Matrix(const Matrix& mat){
mat_row = mat.mat_row;
mat_col = mat.mat_col;
int size=mat_row*mat_col;
matrix= new int [size];
for(int i=0;i<size;i++){
matrix[i]=mat.matrix[i];
}
}
It looks like you have the exact same problem in you operator=() as well.
In the code where you indicate that your problem shows up you do not have an lvalue. You have mat1+mat2; so the result of that addition ends up being unused.
Also, your operator+() should be taking a const ref to the matrix and that is your actual issue. Passing by value like you currently are will cause a temporary copy which is created through the copy constructor.
I have a problem with sorting. I sort the objects containing the dynamic table. It seems that the stable_sort (or the vector) doesn't use a public copy constructor. I looks like they use a non-existent constructor with no parameter because the tables inside the objects are freed - I think.
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
class Dynamic{
int n;
int *tab;
public:
int getN() const{ return n;}
int *getTab() const {return tab;}
Dynamic(int ile){
n=ile;
tab=new int[n];
for(int i=0; i<n; i++)
tab[i] = (10-i)%10;
}
Dynamic(const Dynamic& d){
n = d.getN();
tab = new int[n];
for(int i=0; i<n; i++)
tab[i] = d.getTab()[i];
}
bool operator<(const Dynamic& a) const{
return n < a.getN();
}
~Dynamic(){
delete[] tab;
}
};
int test(vector<Dynamic> & c){
vector<Dynamic> d(c);
stable_sort(d.begin(), d.end());
d.clear();
}
int main(){
vector<Dynamic> c;
c.push_back(Dynamic(15));
test(c);
cout<<"test!";
return 0;
}
STL's sort is also affected but in slightly more complex way.
In g++-4.7.2 I can compile this and in running I get "double free or corruption (fasttop)"/core dumped (full report isn't helpful, I think). On online g++-4.9.0 it looks similar: "No output: Error: stdout maxBuffer exceeded.".
Where is my mistake? Thank you for your attention.
Well, you didn't overload the operator= for Dynamic, so the compiler implicitly defines one which would do bitwise copy. stable_sort() in your library calls the operator=, so tab in two Dynamic objects points to the same address, as a result, double delete on destruction. Overloading the operator= would resolve the problem:
Dynamic& operator =(const Dynamic& d)
{
// or use the copy-and-swap idiom
if(this != &d)
{
delete [] tab;
n = d.getN();
tab = new int[n];
for (int i = 0; i<n; i++)
tab[i] = d.getTab()[i];
}
return *this;
}
I'm trying to create my own version of an array called a safearray, to test my knowledge of operator overloading and creating proper class's and such.
I'm encountering two errors.
SafeArray.h:11:15: error: ‘const int SafeArray::operator’ cannot be overloaded
SafeArray.h:10:10: error: with ‘int& SafeArray::operator’
My code is split between three files.
Main.cpp
#include <cstdlib>
#include <iostream>
#include "SafeArray.h"
using namespace std;
int main(int argc, char** argv) {
SafeArray a(10); // 10 integer elements
for (int i = 0; i < a.length(); i++) {
cout << i << " " << a[i] << "s" << endl; // values initialise to 0
}
cout << endl << a[1]; // Program exits here.
a[3] = 42;
cout << a[3];
a[10] = 10;
cout << a[10];
a[-1] = -1; // out-of-bounds is "safe"?
SafeArray b(20); // another array
b = a; // array assignment
for (int i = 0; i < b.length(); i++) {
cout << b[i] << endl; // values copied from a
}
return 0;
}
SafeArray.h
#ifndef SAFEARRAY_H
#define SAFEARRAY_H
class SafeArray {
public:
SafeArray(int); // int variable will be the array size
int length();
int boundsCheck(int y); // constructor will call this function
// const SafeArray operator= (const SafeArray&);
int& operator[] (int y);
const int operator [] (const int y); // you need this one too.
SafeArray &operator=(SafeArray rhs) {
std::swap(array, rhs.array);
std::swap(length_, rhs.length_);
}
SafeArray(SafeArray const &other);
~SafeArray();
private:
int length_;
int *array;
//int array[];
};
#endif /* SAFEARRAY_H */
SafeArray.cpp
#include "SafeArray.h"
#include <iostream>
SafeArray::SafeArray(int x) {
length_ = x;
array = new int[length];
for (int i = 0; i < length_; i++) {
array[i] = 0;
}
}
int SafeArray::length() {
return this->length_;
}
int SafeArray::boundsCheck(int y) {
}
int& SafeArray::operator[] (int y) {
return array[y];
}
SafeArray::~SafeArray() {
delete [] array;
}
SafeArray::SafeArray(SafeArray const &other) {
int *temp = new int[rhs.size_];
for (int i=0; i<rhs.size_; i++)
temp[i] = rhs.array[i];
std::swap(temp, array);
delete [] temp;
return *this;
}
Your class definition isn't valid. int array[] is an incomplete type, which must not appear as a (non-static) class member. Some compilers accept this as a synonym for int array[0], but zero-sized arrays are not valid in C++, either (only in C99).
In short, you cannot write your code the way you do. You need to learn about dynamic allocation and manage your own memory. Check out how std::vector is implemented.
In C++11, I might recommend a std::unique_ptr<int[]> array as a quick-fix approach, to be initialized as array(new int[x]).
Actually int array[] is valid, and may appear as a class member. The following compiles with strict C++11 conformance:
class foo
{
public:
foo() {}
int length;
int A[];
};
void ralph()
{
foo *bar = (foo *)new int[ 21 ];
bar->length = 20;
bar->A[0] = 1;
}
This is legal, and has its advantages (occasionally). Although it is not commonly used.
However, I suspect that the OP wanted something more along the lines of
class SafeArray {
public:
SafeArray(int); // int variable will be the array size
int length();
int boundsCheck(int y); // constructor will call this function
int& operator[] (int y);
const int operator [] (const int y) // you need this one too.
private:
int length_;
int *array;
};
along with
SafeArray::SafeArray(int x) {
length_ = x;
array = new int[length];
for (int i = 0; i < length_; i++) {
array[i] = 0;
}
}
As #Kerrek already pointed out, your class definition is clearly wrong (shouldn't compile).
To fix it, you want to change the definition to something like:
int *array;
Then in your default ctor you could use something like this:
SafeArray::SafeArray(unsigned size = 0)
: array(new int[size])
{
for (unsigned i=0; i<size; i++)
array[i] = 0;
}
Then, yes, you'll need to write an assignment operator. The usual way is called the copy and swap idiom. You create a copy, then swap the contents of the current one with those of the copy:
SafeArray &operator=(SafeArray rhs) {
std::swap(array, rhs.array);
std::swap(length_, rhs.length_);
}
Along with that, you'll need a copy constructor that makes a copy of the data as well:
SafeArray::SafeArray(SafeArray const &other) {
int *temp = new int[rhs.size_];
for (int i=0; i<rhs.size_; i++)
temp[i] = rhs.array[i];
std::swap(temp, array);
delete [] temp;
return *this;
}
Finally, you'll need a destructor to destroy an object and (particularly) delete the memory it holds:
SafeArray::~SafeArray() {
delete [] array;
}
Then realize that all of that is an ugly mess that will never really work well. In particular, the basic methodology is restricted to an array that's basically fixed in size. As long as you only store ints, it's fairly easy to overlook the problems, and make a dynamic array that (sort of) works. When/if you want to store some other type, however, you just about need to separate allocating memory from initializing objects in that memory, which means throwing away essentially all the code above, and replacing it with something that:
keeps track of the array size and allocation size separately
allocates memory with ::operator new, an Allocator object, or something else similar
uses placement new to initialize objects in the memory when needed.
uses explicit destructor calls to destroy the objects
uses ::operator delete to release memory
and so on. To summarize, std::vector is not a trivial piece of work.
The error message refers to these two lines:
int& operator[] (int y);
const int operator [] (const int y); // you need this one too.
Your error message says that (int y) and (const int y) are too similar to be two different overloads of the [] operator. You cannot overload on (int y) and (const int y) because the calls would all be ambiguous.
You probably meant to return a const int if your SafeArray is const, but return an int& if your SafeArray is not const. In that case, you declare the second function to apply to const SafeArray, by putting the word const after the parameter list. This is what you should write in SafeArray.h:
int& operator[] (int y);
const int operator [] (int y) const; // you need this one too.
You would then have to write both of these functions in SafeArray.cpp:
int& SafeArray::operator[] (int y) {
return array[y];
}
const int SafeArray::operator[] (int y) const { // you need this one too.
return array[y];
}