Adding 2d Array to 1d Array - c++

The code is supposed to create a 2d array fill it with some values then put the values into 1d array and add
**I have this function called AddTab that should add the 2d array to 1d array.
#include "pch.h"
#include <iostream>
using namespace std;
int **createTab(int n, int m)
{
int **tab = nullptr;
try {
tab = new int *[n];
}
catch (bad_alloc)
{
cout << "error";
exit(0);
}
for (int i = 0; i < n; i++)
{
try {
tab[i] = new int[m] {};
}
catch (bad_alloc)
{
cout << "error";
exit(0);
}
}
return tab;
}
void FillTab(int m, int n, int **tab)
{
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> tab[i][j];
}
}
}
void AddTab(int **tab,int n,int m)
{
int *temp_tab=new int[m];
memset(temp_tab, 0, sizeof(temp_tab));
for (int i=0;i<m;i++)
{
for (int j=0;j<n;j++)
{
temp_tab[j] += tab[i][j];
cout << temp_tab[j] << "( " << j << ")" << endl;
}
}
}
int main()
{
int **X = nullptr;
X = createTab(3, 3);
FillTab(3, 3, X);
AddTab(X, 3, 3);
}
I filled the 3x3 2d tab with 1's.
For the first loop it was supposed to be {1,1,1} but instead something weird pops up.
1( 0)
-842150450( 1)
-842150450( 2)
2( 0)
-842150449( 1)
-842150449( 2)
3( 0)
-842150448( 1)
-842150448( 2)
What can I do so it will work fine?

sizeof(temp_tab)
for
int *temp_tab
returns 4/8 bytes, it depends on system. So only first 4/8 bytes are set to 0 for your dynamic allocated array. If temp_tab[j] is not set to 0, by doing temp_tab[j] += tab[i][j]; you update garbage value and finally as result you get garbage value as well.
Fix:
memset(temp_tab, 0, sizeof(int) * m);

Related

Arrays aren't behaving as I'm expecting

Pointers are still a little confusing to me. I want the split function to copy negative elements of an array into a new array, and positive elements to be copied into another new array. A different function prints the variables. I've included that function but I don't think it is the problem. When the arrays are printed, all elements are 0:
Enter number of elements: 5
Enter list:1 -1 2 -2 3
Negative elements:
0 0
Non-Negative elements:
0 0 0
I assume that the problem is that in the split function below i need to pass the parameters differently. I've tried using '*' and '**' (no quotes) for passing the parameters but I get error messages, I may have done so incorrectly.
void split(int alpha[], int bravo[], int charlie[], int aSize, int bSize, int cSize) {
int a = 0;
int b = 0;
for (int i = 0; i < aSize; ++i) {
if (alpha[i] < 0) {
alpha[i] = bravo[a];
++a;
}
else {
alpha[i] = charlie[b];
++b;
}
}
if (a + b != aSize) {
cout << "SOMETHING HAS GONE HORRIBLY WRONG!";
exit(0);
}
}
my main function (all arrays are required to be pointers):
int num_elements;
cin >> num_elements;
int * arr1 = new int[num_elements];
int x;
cout << "Enter list:";
for (int i = 0; i < num_elements; ++i) {
cin >> x;
arr1[i] = x;
}
int y = 0;
int z = 0;
count(arr1, num_elements, y, z);
int * negs = new int [y];
int * nonNegs = new int[z];
split(arr1, negs, nonNegs, num_elements, y, z);
cout << "Negative elements:" << endl;
print_array(negs, y);
cout << endl;
cout << "Non-Negative elements:" << endl;
print_array(nonNegs, z);
cout << endl;
All functions:
void count(int A[], int size, int & negatives, int & nonNegatives) {
for (int i = 0; i < size; ++i) {
if (A[i] < 0) {
++negatives;
}
if (A[i] >= 0) {
++nonNegatives;
}
}
}
void split(int alpha[], int bravo[], int charlie[], int aSize, int bSize, int cSize) {
int a = 0;
int b = 0;
for (int i = 0; i < aSize; ++i) {
if (alpha[i] < 0) {
alpha[i] = bravo[a];
++a;
}
else {
alpha[i] = charlie[b];
++b;
}
}
if (a + b != aSize) {
cout << "SOMETHING HAS GONE HORRIBLY WRONG!";
exit(0);
}
}
void print_array(int A[], int size) {
for (int i = 0; i < size; ++i) {
cout << A[i] << " ";
}
}
All help is appreciated.
EDIT: I apologize for my unclear question, I was wondering how to get my arrays to behave as I want them to.
Array is behaving correctly as per instruction :), you are doing minor mistake (may be overlook) in split function. I have commented out the statement and given reason of problem, please correct those two line of code, rest is fine.
void split(int alpha[], int bravo[], int charlie[], int aSize, int bSize, int cSize) {
int a = 0;
int b = 0;
for (int i = 0; i < aSize; ++i) {
if (alpha[i] < 0) {
//alpha[i] = bravo[a];// here alpha is your source array, don't overwrite it
bravo[a] = alpha[i];
++a;
}
else {
//alpha[i] = charlie[b];// here alpha is your source array, don't overwrite it
charlie[b] = alpha[i];
++b;
}
}
if (a + b != aSize) {
cout << "SOMETHING HAS GONE HORRIBLY WRONG!";
exit(0);
}
}

Inputting the amount you want displayed in the array

I am writing a program that displays integer arrays. I set the size of the array, but I am wondering how I can ask the user the index of the array that they want listed. Say the const SIZE = 10, and the user wants to see the first three in the array. I want to also write an exception that catches the error if the user input is over the size of the array. If you need to see some code, let me know. Any help is appreciated!
intergerarray.h
class IntArray
{
private:
int *aptr; // Pointer to the array
int arraySize; // Holds the array size
void subscriptError(); // Handles invalid subscripts
public:
class OutOfBoundException
{
public:
int index;
OutOfBoundException(){};
int getInde() { return index; }
};
IntArray(int); // Constructor
IntArray(const IntArray &); // Copy constructor
~IntArray(); // Destructor
int size() const // Returns the array size
{
return arraySize;
}
int &operator[](const int &); // Overloaded [] operator
};
IntergerArray.cpp
IntArray::IntArray(int s)
{
arraySize = s;
aptr = new int[s];
for (int count = 0; count < arraySize; count++)
*(aptr + count) = 0;
}
IntArray::IntArray(const IntArray &obj)
{
arraySize = obj.arraySize;
aptr = new int[arraySize];
for (int count = 0; count < arraySize; count++)
*(aptr + count) = *(obj.aptr + count);
}
IntArray::~IntArray()
{
if (arraySize > 0)
delete[] aptr;
}
void IntArray::subscriptError()
{
cout << "ERROR: Subscript out of range.\n";
exit(0);
}
int &IntArray::operator[](const int &sub)
{
if (sub < 0 || sub >= arraySize)
subscriptError();
return aptr[sub];
}
driver file.cpp
int main()
{
int SIZE = 10;
//int index;
//cout << "enter an index";
//cin >> index;
IntArray table(SIZE);
for (int x = 0; x < SIZE; x++)
table[x] = x;
for (int x = 0; x < SIZE; x++)
cout << table[x] << " ";
cout << endl;
//table[SIZE + 1] = 0;
return 0;
}
Isn't this what you are trying to do? why so much code for such a simple problem?
const int arraySize = 10;
int array[arraySize];
int elementToDis;
do
{
std::cout << "Number of array elements to display: ";
std::cin >> elementToDis;
} while (elementToDis > arraySize || elementToDis < 0); // this is your exeption
for (int ccc(0); ccc < elementToDis; ++ccc)
std::cout << "Index " << ccc << ": " << array[ccc] << '\n';
I think you want to display all elements lower than an index value entered by the user :
Let array[] be the array name of size=10,you can get an index value (say l) from the user and use that value inside a for loop for printing all elements in index lower than l
int array[size]
void disp_in(int l)
{
if(l>=size) // if l greater than or equal to size (as index start at 0)
throw l;
else
{
cout<<"Elements : ";
for(int i=0;i<=l;i++) //if we have say l=2 ,array values in indexes 0,1and 2 will be displayed
cout<<array[i];
}
}
int main ()
{
int l;
cout<<"Enter index : ";
cin>>l; //till this index value, the array value will be displayed
try
{
disp_in(l);
}
catch(int e)
{
cout<<"Index value greater than max index";
}
return 0;
}
You could try something like this:
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
void print_numbers( const std::vector<int>& array, int nNumbers, const char* pszSeparator )
{
if ( nNumbers > static_cast<int>(array.size()) )
{
throw std::exception();
}
std::copy( array.begin(), array.begin() + nNumbers, std::ostream_iterator<int>( std::cout, pszSeparator ) );
}
int main()
{
std::vector<int> array( 10 );
//Just for testing
{
int n = 0;
auto generator = [n]() mutable
{
return n++;
};
std::generate_n( array.begin(), array.size(), generator );
}
try
{
print_numbers(array, 11, "\n");
}
catch ( std::exception e )
{
std::cout << "Error message..." << std::endl;
}
return 0;
}

Error implementing selection sort in C++

I've written this code to sort an array using selection sort, but it doesn't sort the array correctly.
#include <cstdlib>
#include <iostream>
using namespace std;
void selectionsort(int *b, int size)
{
int i, k, menor, posmenor;
for (i = 0; i < size - 1; i++)
{
posmenor = i;
menor = b[i];
for (k = i + 1; k < size; k++)
{
if (b[k] < menor)
{
menor = b[k];
posmenor = k;
}
}
b[posmenor] = b[i];
b[i] = menor;
}
}
int main()
{
typedef int myarray[size];
myarray b;
for (int i = 1; i <= size; i++)
{
cout << "Ingrese numero " << i << ": ";
cin >> b[i];
}
selectionsort(b, size);
for (int l = 1; l <= size; l++)
{
cout << b[l] << endl;
}
system("Pause");
return 0;
}
I can't find the error. I'm new to C++.
Thanks for help.
The selectionSort() function is fine. Array init and output is not. See below.
int main()
{
int size = 10; // for example
typedef int myarray[size];
myarray b;
for (int i=0;i<size;i++)
//------------^^--^
{
cout<<"Ingrese numero "<<i<<": ";
cin>>b[i];
}
selectionsort(b,size);
for (int i=0;i<size;i++)
//------------^^--^
{
cout<<b[l]<<endl;
}
system("Pause");
return 0;
}
In C and C++, an array with n elements starts with the 0 index, and ends with the n-1 index. For your example, the starting index is 0 and ending index is 9. When you iterate like you do in your posted code, you check if the index variable is less than (or not equal to) the size of the array, i.e. size. Thus, on the last step of your iteration, you access b[size], accessing the location in memory next to the last element in the array, which is not guaranteed to contain anything meaningful (being uninitialized), hence the random numbers in your output.
You provided some sample input in the comments to your question.
I compiled and executed the following, which I believe accurately reproduces your shown code, and your sample input:
#include <iostream>
void selectionsort(int* b, int size)
{
int i, k, menor, posmenor;
for(i=0;i<size-1;i++)
{
posmenor=i;
menor=b[i];
for(k=i+1;k<size;k++)
{
if(b[k]<menor)
{
menor=b[k];
posmenor=k;
}
}
b[posmenor]=b[i];
b[i]=menor;
}
}
int main(int argc, char **argv)
{
int a[10] = {-3, 100, 200, 2, 3, 4, -4, -5, 6, 0};
selectionsort(a, 10);
for (auto v:a)
{
std::cout << v << ' ';
}
std::cout << std::endl;
}
The resulting output was as follows:
-5 -4 -3 0 2 3 4 6 100 200
These results look correct. I see nothing wrong with your code, and by using the sample input you posted, this confirms that.

Vector of Vectors to create matrix

I am trying to take in an input for the dimensions of a 2D matrix. And then use user input to fill in this matrix. The way I tried doing this is via vectors (vectors of vectors). But I have encountered some errors whenever I try to read in data and append it to the matrix.
//cin>>CC; cin>>RR; already done
vector<vector<int> > matrix;
for(int i = 0; i<RR; i++)
{
for(int j = 0; j<CC; j++)
{
cout<<"Enter the number for Matrix 1";
cin>>matrix[i][j];
}
}
Whenever I try to do this, it gives me a subscript out of range error. Any advice?
You have to initialize the vector of vectors to the appropriate size before accessing any elements. You can do it like this:
// assumes using std::vector for brevity
vector<vector<int>> matrix(RR, vector<int>(CC));
This creates a vector of RR size CC vectors, filled with 0.
As it is, both dimensions of your vector are 0.
Instead, initialize the vector as this:
vector<vector<int> > matrix(RR);
for ( int i = 0 ; i < RR ; i++ )
matrix[i].resize(CC);
This will give you a matrix of dimensions RR * CC with all elements set to 0.
I'm not familiar with c++, but a quick look at the documentation suggests that this should work:
//cin>>CC; cin>>RR; already done
vector<vector<int> > matrix;
for(int i = 0; i<RR; i++)
{
vector<int> myvector;
for(int j = 0; j<CC; j++)
{
int tempVal = 0;
cout<<"Enter the number for Matrix 1";
cin>>tempVal;
myvector.push_back(tempVal);
}
matrix.push_back(myvector);
}
Assume we have the following class:
#include <vector>
class Matrix {
private:
std::vector<std::vector<int>> data;
};
First of all I would like suggest you to implement a default constructor:
#include <vector>
class Matrix {
public:
Matrix(): data({}) {}
private:
std::vector<std::vector<int>> data;
};
At this time we can create Matrix instance as follows:
Matrix one;
The next strategic step is to implement a Reset method, which takes two integer parameters that specify the new number of rows and columns of the matrix, respectively:
#include <vector>
class Matrix {
public:
Matrix(): data({}) {}
Matrix(const int &rows, const int &cols) {
Reset(rows, cols);
}
void Reset(const int &rows, const int &cols) {
if (rows == 0 || cols == 0) {
data.assign(0, std::vector<int>(0));
} else {
data.assign(rows, std::vector<int>(cols));
}
}
private:
std::vector<std::vector<int>> data;
};
At this time the Reset method changes the dimensions of the 2D-matrix to the given ones and resets all its elements. Let me show you a bit later why we may need this.
Well, we can create and initialize our matrix:
Matrix two(3, 5);
Lets add info methods for our matrix:
#include <vector>
class Matrix {
public:
Matrix(): data({}) {}
Matrix(const int &rows, const int &cols) {
Reset(rows, cols);
}
void Reset(const int &rows, const int &cols) {
data.resize(rows);
for (int i = 0; i < rows; ++i) {
data.at(i).resize(cols);
}
}
int GetNumRows() const {
return data.size();
}
int GetNumColumns() const {
if (GetNumRows() > 0) {
return data[0].size();
}
return 0;
}
private:
std::vector<std::vector<int>> data;
};
At this time we can get some trivial matrix debug info:
#include <iostream>
void MatrixInfo(const Matrix& m) {
std::cout << "{ \"rows\": " << m.GetNumRows()
<< ", \"cols\": " << m.GetNumColumns() << " }" << std::endl;
}
int main() {
Matrix three(3, 4);
MatrixInfo(three);
}
The second class method we need at this time is At. A sort of getter for our private data:
#include <vector>
class Matrix {
public:
Matrix(): data({}) {}
Matrix(const int &rows, const int &cols) {
Reset(rows, cols);
}
void Reset(const int &rows, const int &cols) {
data.resize(rows);
for (int i = 0; i < rows; ++i) {
data.at(i).resize(cols);
}
}
int At(const int &row, const int &col) const {
return data.at(row).at(col);
}
int& At(const int &row, const int &col) {
return data.at(row).at(col);
}
int GetNumRows() const {
return data.size();
}
int GetNumColumns() const {
if (GetNumRows() > 0) {
return data[0].size();
}
return 0;
}
private:
std::vector<std::vector<int>> data;
};
The constant At method takes the row number and column number and returns the value in the corresponding matrix cell:
#include <iostream>
int main() {
Matrix three(3, 4);
std::cout << three.At(1, 2); // 0 at this time
}
The second, non-constant At method with the same parameters returns a reference to the value in the corresponding matrix cell:
#include <iostream>
int main() {
Matrix three(3, 4);
three.At(1, 2) = 8;
std::cout << three.At(1, 2); // 8
}
Finally lets implement >> operator:
#include <iostream>
std::istream& operator>>(std::istream& stream, Matrix &matrix) {
int row = 0, col = 0;
stream >> row >> col;
matrix.Reset(row, col);
for (int r = 0; r < row; ++r) {
for (int c = 0; c < col; ++c) {
stream >> matrix.At(r, c);
}
}
return stream;
}
And test it:
#include <iostream>
int main() {
Matrix four; // An empty matrix
MatrixInfo(four);
// Example output:
//
// { "rows": 0, "cols": 0 }
std::cin >> four;
// Example input
//
// 2 3
// 4 -1 10
// 8 7 13
MatrixInfo(four);
// Example output:
//
// { "rows": 2, "cols": 3 }
}
Feel free to add out of range check. I hope this example helps you :)
try this. m = row, n = col
vector<vector<int>> matrix(m, vector<int>(n));
for(i = 0;i < m; i++)
{
for(j = 0; j < n; j++)
{
cin >> matrix[i][j];
}
cout << endl;
}
cout << "::matrix::" << endl;
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
Vector needs to be initialized before using it as cin>>v[i][j]. Even if it was 1D vector, it still needs an initialization, see this link
After initialization there will be no errors, see this link
What you have initialized is a vector of vectors, so you definitely have to include a vector to be inserted("Pushed" in the terminology of vectors) in the original vector you have named matrix in your example.
One more thing, you cannot directly insert values in the vector using the operator "cin". Use a variable which takes input and then insert the same in the vector.
Please try this out :
int num;
for(int i=0; i<RR; i++){
vector<int>inter_mat; //Intermediate matrix to help insert(push) contents of whole row at a time
for(int j=0; j<CC; j++){
cin>>num; //Extra variable in helping push our number to vector
vin.push_back(num); //Inserting numbers in a row, one by one
}
v.push_back(vin); //Inserting the whole row at once to original 2D matrix
}
I did this class for that purpose. it produces a variable size matrix ( expandable) when more items are added
'''
#pragma once
#include<vector>
#include<iostream>
#include<iomanip>
using namespace std;
template <class T>class Matrix
{
public:
Matrix() = default;
bool AddItem(unsigned r, unsigned c, T value)
{
if (r >= Rows_count)
{
Rows.resize(r + 1);
Rows_count = r + 1;
}
else
{
Rows.resize(Rows_count);
}
if (c >= Columns_Count )
{
for (std::vector<T>& row : Rows)
{
row.resize(c + 1);
}
Columns_Count = c + 1;
}
else
{
for (std::vector<T>& row : Rows)
{
row.resize(Columns_Count);
}
}
if (r < Rows.size())
if (c < static_cast<std::vector<T>>(Rows.at(r)).size())
{
(Rows.at(r)).at(c) = value;
}
else
{
cout << Rows.at(r).size() << " greater than " << c << endl;
}
else
cout << "ERROR" << endl;
return true;
}
void Show()
{
std::cout << "*****************"<<std::endl;
for (std::vector<T> r : Rows)
{
for (auto& c : r)
std::cout << " " <<setw(5)<< c;
std::cout << std::endl;
}
std::cout << "*****************" << std::endl;
}
void Show(size_t n)
{
std::cout << "*****************" << std::endl;
for (std::vector<T> r : Rows)
{
for (auto& c : r)
std::cout << " " << setw(n) << c;
std::cout << std::endl;
}
std::cout << "*****************" << std::endl;
}
// ~Matrix();
public:
std::vector<std::vector<T>> Rows;
unsigned Rows_count;
unsigned Columns_Count;
};
'''

Superfluous characters printed by cout when using exception::what()

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.