Related
I am struggling to fix a piece of code, even though I believe I know the cause. I did search a lot on Stack Overflow and many people had similar issues (and good answers were provided), but still, I am not sure I understand the problem with my code.
I tried giving a smaller example, but the structure I have is not simple by itself. I hope the following is simple enough.
My objective on the excerpt:
Have a vector of points.
Have a vector of segments. (Whose endpoints are reference to points in the vector above)
Have a vector of events. (That keep a reference to the exhisting segments and points)
segment::segment (point &pt1, point&pt2, int i) {
s = &pt1; e = &pt2; ind = i; // point *s, point *e, int ind
}
event::event (segment &s, point &pt, int tp) {
seg = &s; type = tp; p = &pt; //segment *seg, int type, point *p
}
void pre_process (int size, std::vector<point>& pts, std::vector<event>& evts,
std::vector<segment>& segs) {
float x, y;
for (int i = 0; i < size; ++ i) {
std::cin >> x >> y;
pts.push_back({x,y});
}
for (int i = 0; i < size; ++i) {
int j = (i+1)%size;
if (cmpXY(pts[i], pts[j]))
segs.push_back({pts[i], pts[j], i});
else
segs.push_back({pts[j], pts[i], i});
evts.push_back({segs[i], *segs[i].s, 0});
evts.push_back({segs[i], *segs[i].e, 1});
std::cout << 2*i << "\n";
std::cout << segs[i].s << "\n"; //ALWAYS EQUAl
std::cout << evts[2*i].seg->s << "\n";
} // LINE X
for (int i = 0; i < size; ++i) { //LINE Y
std::cout << 2*i << "\n";
std::cout << segs[i].s << "\n"; //DIFFERENT SOMETIMES
std::cout << evts[2*i].seg->s << "\n";
}
So, the problem is that some of addresses my objects are pointing to change from LINE X to LINE Y. In particular, pts and segs remain the same.
From what I know and from what I understood here or here I cannot get the reference to an object on the stack of any function (my for loop, for example). However, I believe the lifetime of the object on the container is the same as the container itself. It makes me believe that all objects I push_back() should persist through the function pre_proccess and the function that is calling it.
push_back on vector (might) invalidate previous reference/iterator.
it happens in the loop there
if (cmpXY(pts[i], pts[j]))
segs.push_back({pts[i], pts[j], i});
else
segs.push_back({pts[j], pts[i], i});
evts.push_back({segs[i], *segs[i].s, 0});
you have to reserve enough place in segs to avoid reallocation (or change the logic).
It looks that the vector resize itself and had to be relocated (which will invalidate all iterator references).
Try to use std::vector::reserve before processing:
void pre_process (int size, std::vector<point>& pts, std::vector<event>& evts,
std::vector<segment>& segs) {
pts.reserve(size);
evts.reserve(size);
segs.reserve(size);
float x, y;
for (int i = 0; i < size; ++ i) {
std::cin >> x >> y;
pts.push_back({x,y});
}
for (int i = 0; i < size; ++i) {
int j = (i+1)%size;
if (cmpXY(pts[i], pts[j]))
segs.push_back({pts[i], pts[j], i});
else
segs.push_back({pts[j], pts[i], i});
evts.push_back({segs[i], *segs[i].s, 0});
evts.push_back({segs[i], *segs[i].e, 1});
std::cout << 2*i << "\n";
std::cout << segs[i].s << "\n"; //ALWAYS EQUAl
std::cout << evts[2*i].seg->s << "\n";
} // LINE X
for (int i = 0; i < size; ++i) { //LINE Y
std::cout << 2*i << "\n";
std::cout << segs[i].s << "\n"; //DIFFERENT SOMETIMES
std::cout << evts[2*i].seg->s << "\n";
}
I'm having problems with code I'm writing to solve give mazes using class Templates and stacks. The algorithm worked well enough before I implemented code to be able to read mazes from files. Now it doesn't solve the maze, it only outputs "Stack is full! Can not push" and prints the maze. The algorithm I'm adhering goes like:
Define the two-dimensional int array M as given
above, and two int stacks which will store the row
and column index of the locations we have checked.
Search the array M to locate the entry 2 to find your
starting point
Push the current location (i.e., the row and column
index) onto the () stacks.
Check if the value stored at the current location is
a 3; if it is, we are done. If not, set it to 2.
Check the current location's four neighbours in order (e.g., clockwise from north). If any is a 1 or a
3, pop that location onto the stack and move there
next.
If none of the neighbours store a 1, we are at a
dead-end: set the value at that location to 0, and
pop the new location from the stack.
Any help is appreciated!
#include <iostream>
#include <fstream>
#include <string>
#define MAX_STACK 10
void PrintMaze(int **Maze, int M, int N);
template <class T>
class MyStack {
private:
T *contents;
int top, maxsize;
public:
~MyStack(void);
MyStack (void);
MyStack (unsigned int StackSize);
bool checkEmpty(void);
bool checkFull(void);
void push(T c);
T pop(void );
int scon(void);
};
template <class T> MyStack<T>::~MyStack(void)
{
delete [] contents;
}
template <class T> MyStack<T>::MyStack(void)
{
top=0;
contents = new T [MAX_STACK];
maxsize = MAX_STACK;
}
template <class T> MyStack<T>::MyStack(unsigned int StackSize)
{
top=0;
maxsize = StackSize;
contents = new T[StackSize];
}
template <class T> bool MyStack<T>::checkEmpty(void)
{
return MAX_STACK == 0;
}
template <class T> bool MyStack<T>::checkFull(void)
{
return MAX_STACK == 10;
}
template <class T> void MyStack<T>::push(T c)
{
if(checkFull())
{
std::cout << "Stack is fulL! Can not push" << std::endl;
}
else
{
contents[top]=c;
top++;
}
}
template <class T> T MyStack<T>::pop(void)
{
top--;
return(contents[top]);
if(checkEmpty())
{
std::cout << "Stack empty! Can not pop" << std::endl;
return 0;
}
else
{
top--;
return(contents[top]);
}
}
template <class T> int MyStack<T>::scon(void)
{
return(*contents);
}
int main(void )
{
// Open the file
std::ifstream InFile;
InFile.open("C:/Users/Desktop/Computer Science/Maze6.txt");
if (InFile.fail())
{
std::cerr << "Error - cannot open Maze.txt" << std::endl;
return(1);
}
// Read the size of the maze
int Rows, Cols;
InFile >> Rows >> Cols;
std::cout << "The maze has " << Rows << " rows and " << Cols << " columns." << std::endl;
// Dynamically assign memory for the array
int **M = new int*[Rows];
for(int i = 0; i < Rows; ++i)
{
M[i] = new int[Cols];
}
/// Read in the data
for (int i=0; i<Rows; i++)
for (int j=0; j<Cols; j++)
{
char c;
InFile >> c;
M[i][j] = (int)(c-'0');
}
// Display the maze
std::cout << "Here is the maze: ";
PrintMaze(M, Rows, Cols);
//////////////////////////////
MyStack<int> s1;
MyStack<int> s2;
for(int Rows=0; Rows<sizeof(M); Rows++)
{
for(int Cols=0; Cols<sizeof(M); Cols++)
{
if(M[Rows][Cols] == 2)
{
s1.push(Rows);
s2.push(Cols);
if(Rows-1 == 1)
{
s1.push(Rows-1);
s2.push(Cols-1);
M[Rows-1][Cols] == 2;
}
if(Cols+1 == 1)
{
s1.push(Rows);
s2.push(Cols+1);
M[Rows][Cols+1] == 2;
}
if(Rows+1 == 1)
{
s1.push(Rows+1);
s2.push(Cols);
M[Rows-1][Cols] == 2;
}
if(Cols-1 == 1)
{
s1.push(Rows);
s2.push(Cols-1);
M[Rows][Cols-1] == 2;
}
else
{
M[Rows][Cols] = 0;
s1.pop();
s2.pop();
}
}
if(M[Rows][Cols] == 3)
{
std::cout << "Maze completed! Item found at row: " << Rows << " column: " << Cols << std::endl;
std::cout << "Column path: " << s2.scon() << std::endl;
std::cout << "Row path: " << s1.scon() << std::endl;
}
else
{
M[Rows][Cols] == 2;
}
}
}
//////////////////////////////
// Deallocate memory
for(int i =0; i<6; i++)
{
for(int j = 0; j<6; j++)
{
std::cout <<M[i][j] << ' ';
}
std::cout << std::endl;
}
return (0);
}
void PrintMaze(int **Maze, int M, int N)
{
std::cout << std::endl;
for(int i = 0; i<M; i++)
{
for(int j=0; j<N; j++)
{
std::cout << Maze[i][j];
}
std::cout << std::endl;
}
}
sizeof(M) is wrong, it will give you the size of the pointer M itself, not the size of what it points to. You need to explicitly use the Rows and Cols variables, using their original values, and use different values for iterating over the rows and the columns.
As in
//////////////////////////////
MyStack<int> s1;
MyStack<int> s2;
for(int i=0; i<Rows; i++)
{
for(int j=0; j<Cols; j++)
{
// Use i and j as indexes...
}
}
I defined an empty vector of vectors :
vector< vector<int> > v;
How do i fill that empty vector with vector of size 2 integers ( from input ) each iteration of while loop?
while ( cin >> x >> y ) {
//....
}
Will this one work? Or what's the best and most elegant / effective way of doing it?
while ( cin >> x >> y )
{
vector<int> row;
row.push_back( x );
row.push_back( y );
v.push_back( row );
}
As pointed out by JerryCoffin, you probably better use a :
struct Point {
int x;
int y;
};
and then you might overload the output operator
std::ostream& operator<< (std::ostream& o,const Point& xy){
o << xy.x << " " << xy.y;
return o;
}
and similar the input operator (see e.g. here). And then you can use it like this:
int main() {
Point xy;
std::vector<Point> v;
v.push_back(xy);
std::cout << v[0] << std::endl;
return 0;
}
The another way of doing so is to push the value in a 1-D vector and then push that 1-D vector in 2-D vector. I have also printed the values as a test.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t,n,temp;
cin>>t;
vector<vector<int>> value;
for(int i=0;i<t;i++)
{
cin>>n;
vector<int> x;
for(int j=0;j<n;j++)
{
cin>>temp;
x.push_back(temp);
}
value.push_back(x);
}
for(int i=0;i<t;i++)
{
for(int j=0;j<value[i].size();j++)
{
cout<<value[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
Hope it helps!!
I wrote it - compilator didnt say anything but i have never used vectors so i haven't figured out how to print it yet
You can print using for example a range based for loop (C++11):
for (const auto &vec : v) { // for every vector in v
for (const auto &num : vec) // print the numbers
cout << num << " ";
cout << '\n';
}
And regular for loop:
for (unsigned int i = 0; i != v.size(); ++i) {
for (unsigned int j = 0; j != v[i].size(); ++j) {
cout << v[i][j] << " ";
}
cout << '\n';
}
I have a 3D string vector in C++:
vector<vector<vector<string>>> some_vector
That I am trying is to find a fast method to allocate memory for it.
I tried to define it with two different methods as follow:
#include<vector>
#include<iostream>
#include<ctime>
using namespace std;
#define DIM1 100
#define DIM2 9
#define DIM3 120
int main()
{
clock_t t1_start = clock();
vector<vector<vector<string>>> vec1(DIM1, vector<vector<string>>(DIM2, vector<string>(DIM3)));
clock_t t1_end = clock();
double diff1 = (t1_end - t1_start) / double(CLOCKS_PER_SEC);
clock_t t2_start = clock();
vector<vector<vector<string>>> vec2;
vec2.resize(DIM1);
for(int i = 0; i < DIM1; i++)
{
vec2[i].resize(DIM2);
for(int j = 0; j < DIM2; j++)
vec2[i][j].resize(DIM3);
}
clock_t t2_end = clock();
double diff2 = (t2_end - t2_start) / double(CLOCKS_PER_SEC);
cout<<"1st definition used time: "<<diff1<<"s"<<endl;
cout<<"2nd definition used time: "<<diff2<<"s"<<endl;
}
I expect that the first method (vec1) could be faster than the 2nd one (vec2).
But it turned out that the 1st method is much slower than the 2nd. On my machine, the 1st method used 0.245 seconds, while the 2nd method used 0.152 seconds.
Moreover, when I switch the data type to int, the 1st one took 0.058 second, and the 2nd took 0.004.
May I know what cause such difference? And is there better way to allocate memory for a 3D vector?
Many thanks in advance.
May I know what cause such difference?
The first version constructs a 2-d vector by copying a 1-d vector, and then constructs the 3-d vector by copying that. This might be slower than resizing the vectors without copying. However, I'd hope that the difference would be negligible if you're building with optimisation.
And is there better way to allocate memory for a 3D vector?
It might be better to use a single contiguous array, wrapped in a class that provides multi-dimensional accessors. This would make allocation much simpler, and would also avoid some pointer dereferencing when accessing elements (at the cost of a bit of arithmetic). Something like this:
template <typename T>
class vector3d {
public:
vector3d(size_t d1=0, size_t d2=0, size_t d3=0, T const & t=T()) :
d1(d1), d2(d2), d3(d3), data(d1*d2*d3, t)
{}
T & operator()(size_t i, size_t j, size_t k) {
return data[i*d2*d3 + j*d3 + k];
}
T const & operator()(size_t i, size_t j, size_t k) const {
return data[i*d2*d3 + j*d3 + k];
}
private:
size_t d1,d2,d3;
std::vector<T> data;
};
I think I'd optimize it by allocating one large block of memory instead of a lot of little ones. This one is only 2D instead of 3D, but gives the basic idea:
template <class T>
class matrix {
size_t columns_;
std::vector<T> data;
public:
matrix(size_t columns, size_t rows) : columns_(columns), data(columns*rows) {}
T &operator()(size_t column, size_t row) { return data[row*columns_+column]; }
};
For 3D, you'll need to deal with "planes" (or something) along with rows and columns, but the basic idea is pretty much the same.
I added several features to Mike Seymour's code such as dynamically resize the 3d vector and on access/assign bounds checking for data vector.
template <typename T>
class vector3d
{
public:
vector3d(size_t d1=0, size_t d2=0, size_t d3=0, T const & t=T()) :
d1(d1), d2(d2), d3(d3), data(d1*d2*d3, t)
{}
T & operator()(size_t i, size_t j, size_t k)
{
return (i<=d1 && j<=d2 && k<=d3) ? data[i*d2*d3 + j*d3 + k]
: data.at(i*d2*d3 + j*d3 + k);
}
T const & operator()(size_t i, size_t j, size_t k) const
{
return data[i*d2*d3 + j*d3 + k];
}
void resize(const size_t _d1=0, const size_t _d2=0, const size_t _d3=0)
{
data.resize(_d1*_d2*_d3);
d1=_d1;
d2=_d2;
d3=_d3;
}
void shrink_to_fit()
{
data.shrink_to_fit();
}
const size_t length() const
{
return data.size();
}
const size_t capacity() const
{
return data.capacity();
}
const size_t x() const
{
return d1;
}
const size_t y() const
{
return d2;
}
const size_t z() const
{
return d3;
}
private:
size_t d1,d2,d3;
std::vector<T> data;
};
Usage:
vector3d<int> vec3d(2,2,2,31); //create 2x2x2 3d vector and fill it with 31
vec3d(1,1,2)=45; //assign 45 at vec3d(1,1,2)
vec3d.resize(2,2,1); //resize the vec3d to 2x2x1
vec3d(1,2,2)=67; //error (its out of bounds)
To initialize a 3D string vector you shall initialize the vector structure for each dimension one at a time and for each index, for instance:
vector<vector<vector<string> > > myvector; //declare the 3D vector
for(k=0; k<3; k++)
{
myvector.push_back(vector<vector<string> >()); //initialize the first index with a 2D vector
for(i=0; i<4; i++)
{
myvector[k].push_back(vector<string>()); //initialize the 2 index with a row of strings
for(j=0; j<4; j++)
{
result = " whatever you want to insert in the vector element";
myvector[k][i].push_back(result); //fulfill the last index regularly
}
}
}
When you initialize a vector of vectors in the first method, a temporary vector is allocated and then copied into the outer vector the required number of times. This means you have an extra allocation that is unnecessary and the new elements are initialized by copying their value from another data structure, which uses more memory accesses.
Resizing the vectors as per the second method is more ugly but avoids the extra allocation. Furthermore the new elements are created by the default constructor and do not need to copy from other vectors. This will also be faster.
If speed matters (and maybe it doesn't, premature optimization and all that), then you must use the second method (OR a single-block allocation as suggested by the other answers). I don't have faith that a compiler can simply "optimize" away the inefficiency of the first method.
Here is an example of various dimensions of vectors in case anyone out there cares. I know when I was starting out it was a pain to find how to give initial values to multidimension vectors as I couldn't find any examples;
// This simple project demonstrates a single vector, a 2D vector, a 3D vector and a 4D vector in C++
//
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> myVector = { 0,1,2,3,4,5,6 };
vector<vector<int>> my2dVector = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25},{0,-1,-2,-3,-4},{-6,7,22,-15,-25},{true,true,false,true,false} };
vector < vector < vector<int>>> my3dVector =
{
{
{1,2,3},
{4,5,6}, // plane 0
{7,8,9}
},
{
{-1,-2,-3},
{-4,-5,-6}, // plane 1
{-10,-22,36}
},
{
{129,212,999},
{0,0,1}, // plane 2
{false,true,false}
}
};
vector<vector<vector<vector<int>>>> my4dVector =
{
{ //Cube 0
{
{1,2,3},
{4,5,6}, // plane 0
{7,8,9}
},
{
{-1,-2,-3},
{-4,-5,-6}, // plane 1
{-10,-22,36}
},
{
{129,212,999},
{0,0,1}, // plane 2
{false,true,false}
}
},
{ //Cube 1
{
{10,2,-9},
{44,55,60}, // plane 0
{71,85,99}
},
{
{-561,-6562,-453},
{-14,-55,-76}, // plane 1
{-110,-212,316}
},
{
{729,812,456},
{40,10,17}, // plane 2
{true,true,false}
}
}
};
// 1D VECTOR..............
cout << "This is a 1D vector of size " << myVector.size () << "\n";
for (int i = 0; i < myVector.size (); i++)
{
cout << myVector[i] << "\t";
}
cout << "\n\n";
// 2D VECTOR..............
cout << "This is a 2D vector of size " << my2dVector.size () << " X " << my2dVector[0].size () << ".";
if (my2dVector.size () == my2dVector[0].size ()) cout << " This is a square matrix.";
cout << "\n ";
for (int i = 0; i < my2dVector[0].size (); i++)
{
cout << "C" << i << "\t";
}
cout << endl;
for (int i = 0; i < my2dVector.size (); i++)
{
cout << "Row: " << i << " -> ";
for (int j = 0; j < my2dVector[i].size (); j++)
{
if (my2dVector[i][j] >= 0 && my2dVector[i][j] <= 9) cout << " ";
cout << my2dVector[i][j] << "\t";
}
cout << endl;
}
cout << "\n\n";
// 3D VECTOR.................
cout << "This is a 3D vector of size " << my3dVector[0].size () << " X " << my3dVector[0][0].size () << " with " << my3dVector.size () << " planes.\n";
for (int i = 0; i < my3dVector.size (); i++)
{
cout << "Plane #" << i << "\n";
for (int j = 0; j < my3dVector[i].size (); j++)
{
for (int k = 0; k < my3dVector[i][j].size (); k++)
{
cout << my3dVector[i][j][k] << "\t";
}
cout << "\n";
}
}
cout << "\n\n";
//4D VECTOR.................
cout << "This is a 4D vector of size " << my4dVector[0][0].size () << " X " << my4dVector[0][0][0].size () << " with " << my4dVector[0].size () << " planes and " << my4dVector.size () << " cubes.\n";
for (int i = 0; i < my4dVector.size (); i++)
{
cout << "\nCUBE #"<< i<< " _________________\n";
for (int j = 0; j < my4dVector[i].size (); j++)
{
cout << "Plane #" << j << " |\n";
for (int k = 0; k < my4dVector[i][j].size (); k++)
{
for (int l = 0; l < my4dVector[i][j][k].size (); l++)
{
cout << my4dVector[i][j][k][l] << "\t";
}
cout << "|\n";
}
cout << "________________________|\n";
}
cout << "\n";
}
}
I'm sure this is pretty simple, but I couldn't really devise a search query which helped me resolve the issue.
I'd almost be inclined to think this was a bug in the Windows command prompt, except that I've never seen it before, until I started using exceptions, where it occurs if and only if I use exception::what().
This is for a homework assignment, and the program is supposed to compute a series of given problems and display the answers. All of the problems are in a similar vein (matrix/vector arithmetic), and the only ones which cause problems are the problems which are intentionally designed to generate errors, since that's the only time exception::what() is used.
Here's one of the offending problems:
(By the way, is it OK to arbitrarily place these
problems into blocks so that the objects go out of scope and the destructors are called before the next problem, as I've done?)
{ // Problem #9
Vector v1(5);
Matrix m1(3, 3, 1);
try {
v1.set(1, -2);
v1.set(2, -1);
v1.set(3, 4);
v1.set(4, 9);
v1.set(5, 3);
m1.set(1, 1, 12);
m1.set(1, 2, 36);
m1.set(1, 3, -7);
m1.set(2, 1, 4);
m1.set(2, 3, 11);
m1.set(3, 1, 7);
m1.set(3, 2, -5);
m1.set(3, 3, -2);
Vector * ans9 = product(m1, v1);
cout << "Answer to problem 9:" << endl;
ans9->print();
delete ans9;
}
catch(exception & ex) {
cout << "Exception in problem 9: " << ex.what() << endl;
}
} // End problem 9
cout << endl << endl;
The Matrix class and its constructor are nothing special, and the code doesn't throw any exceptions there, so I'll just share the offending product() function:
Vector * product(Matrix &m, Vector &v) {
unsigned int vLength = v.getLength(), mRows = m.getRows(), mCols = m.getCols();
if ( mCols != vLength ) {
throw std::logic_error("matrix/vector product impossible (size mismatch)!");
}
Vector * vprod = new Vector(mRows);
for (unsigned int i = 1; i <= mRows; ++i) {
double value = 0;
for (unsigned int j = 1; j <= vLength; ++j) {
value += (m.get(i, j)) * (v.get(j));
}
vprod->set(i, value);
}
return vprod;
}
And here's an example of the kind of output I get:
I left that ! in there so you can see that it is just printing whatever the last character was right on down that column, until some other character is explicitly printed there.
So, what exactly is going on here? I figure it's probably something to do with string termination, but maybe that's just because I've had too much fun with C in the past.
EDIT: Folks asked for a compilable code segment, and the best I could do was 228 lines. Here goes:
#include <iostream>
#include <iomanip>
#include <cstdlib>
using std::cout;
using std::endl;
using std::exception;
class Vector {
private:
unsigned int length;
double *elements;
public:
Vector(unsigned int desiredLength);
~Vector();
//void dDestroy(Vector &v);
unsigned int getLength();
void set(unsigned int position, double value);
double get(unsigned int position);
void print();
};
Vector::Vector(unsigned int desiredLength) {
length = desiredLength;
elements = new double[length];
for (unsigned int i = 0; i < length; ++i) {
elements[i] = 0;
}
}
Vector::~Vector() {
delete[] elements;
}
unsigned int Vector::getLength() {
return length;
}
void Vector::set(unsigned int position, double value) {
if (position > length || position <= 0) {
throw std::logic_error("vector set failed (out of range)");
}
--position;
elements[position] = value;
}
double Vector::get(unsigned int position) {
if (position > length || position <= 0) {
throw std::logic_error("vector get failed (out of range)");
}
--position;
return elements[position];
}
void Vector::print() {
std::cout << "[ ";
for (unsigned int i=0; i < length; ++i) {
std::cout << elements[i] << " " ;
}
std::cout << "]";
}
class Matrix {
private:
unsigned int rows, cols;
double **elements;
public:
Matrix(unsigned int desiredRows, unsigned int desiredCols, double defaultValue);
~Matrix();
unsigned int getRows();
unsigned int getCols();
void set(unsigned int i, unsigned int j, double value);
double get(unsigned int i, unsigned int j);
void print();
};
Matrix::Matrix(unsigned int desiredRows, unsigned int desiredCols, double defaultValue) {
rows = desiredRows, cols = desiredCols;
// Create
elements = new double*[rows];
for (unsigned int i = 0; i < rows; ++i) {
elements[i] = new double[cols];
}
// Initialize
for (unsigned int i = 0; i < rows; ++i) {
for (unsigned int j = 0; j < cols; ++j) {
elements[i][j] = defaultValue;
}
}
}
Matrix::~Matrix() {
for (unsigned int i = 0; i < rows; ++i) {
delete[] elements[i];
}
delete[] elements;
}
unsigned int Matrix::getRows() {
return rows;
}
unsigned int Matrix::getCols() {
return cols;
}
void Matrix::set(unsigned int i, unsigned int j, double value) {
if (i > rows || j > cols) {
throw std::logic_error("matrix set failed (out of range).");
}
--i, --j;
elements[i][j] = value;
}
double Matrix::get(unsigned int i, unsigned int j) {
if (i > rows || j > cols || i <= 0 || j <= 0) {
throw std::logic_error("matrix get failed (out of range).");
}
--i, --j;
return elements[i][j];
}
void Matrix::print() {
// TODO it would be nice to format based on maximum digits in any value
for (unsigned int i = 0; i < rows; ++i) {
std::cout << "[ ";
for (unsigned int j = 0; j < cols; ++j) {
std::cout << std::setprecision(2) << elements[i][j] << " ";
}
std::cout << "]\n";
}
}
Vector * dot(Vector &v1, Vector &v2) {
if (v1.getLength() != v2.getLength() ) {
throw std::logic_error("dot product impossible (length mismatch)");
}
double result = 0;
for (unsigned int i = 1; i <= v1.getLength(); ++i) {
result += (v1.get(i) * v2.get(i));
}
Vector * vdot = new Vector(1);
vdot->set(1, result);
return vdot;
}
Vector * product(Matrix &m, Vector &v) {
unsigned int vLength = v.getLength(), mRows = m.getRows(), mCols = m.getCols();
if ( mCols != vLength ) {
throw std::logic_error("matrix/vector product impossible (size mismatch)");
}
Vector * vprod = new Vector(mRows);
for (unsigned int i = 1; i <= mRows; ++i) {
double value = 0;
for (unsigned int j = 1; j <= vLength; ++j) {
value += (m.get(i, j)) * (v.get(j));
}
vprod->set(i, value);
}
return vprod;
}
Vector * dot(Vector &v1, Vector &v2);
Vector * product(Matrix &m, Vector &v);
int main() {
cout << endl;
{ // Problem #1
Vector v1(3), v2(3);
try {
v1.set(1, 2);
v1.set(2, 1);
v1.set(3, 3);
v2.set(1, 0);
v2.set(2, 4);
v2.set(3, -9);
Vector * ans1 = dot(v1, v2);
cout << "Answer to problem 1:" << endl;
ans1->print();
delete ans1;
}
catch(const exception & ex) {
cout << "Exception in problem 1: " << ex.what() << endl;
}
} // End problem 1
cout << endl << endl;
{ // Problem #2
Vector v1(2), v2(3);
try {
v1.set(1, 12);
v1.set(2, 1);
v2.set(1, 3);
v2.set(2, -1);
v2.set(3, 5);
Vector * ans2 = dot(v1, v2);
cout << "Answer to problem 2:" << endl;
ans2->print();
delete ans2;
}
catch(const exception & ex) {
cout << "Exception in problem 2: " << ex.what() << endl;
}
} // End problem 2
cout << endl << endl;
}
OK, the comments get a bit crowed and the following is a little to explicit for a comment anyway, so please forgive the not-exactly-an-answer-style of the following.
Since the extra "!" also apears in the line with the prompt, after the program has already exited, it is rather unlikely, that it has something to do with your application. It could be a faulty display driver, or some issue with the Client Server Runtime Sub System / Process (csrss.exe) or the Console Windows Host (conhost.exe), which provide the window when you run console applications.
Also, if the screenshot is not missleading, it looks like the superflous characters (especially visible for the closing parenthesis from "problem 6") are not even fully repeated, but only partial. I.e. the character is somehow "cut".
Anyway, there are some steps you could try to further investigage the problem:
Does it only happen on your system?
Does it only happen with 64bit processes (I assume your having one from the CMD title)
Does it also happen if you're not actually throwing the exception, e.g.
std::logic_error err("blah");
std::cout << err.what() << std::endl;
Can you change your program to use stdio instead of iostreams? And does it still happen then.
Try to redirect the output of the program to a file (e.g. "myapp.exe > foo.txt"). Does the file also contain the extra "!".
I have seen such a behavior under totally different circumstances.
Example:
printf("12345678901234567890\r"); /* carriage return, but no linefeed */
printf("ABCDEFGHIJ\n");
This should output:
ABCDEFGHIJ1234567890
But then, I don't see anything like that (iostreams vs. stdio or not) in your code.
It worries me that you catch 'exception &' instead of 'const exception &'. 'ex' might actually refere to an object that has already been destroyed, so the what() method returns garbage. You must ensure that the 'ex' parameter in your catch-handler, referes to a valid copy of the object originally thrown.