C++ Segmentation fault using cstrings - c++

I am trying to pass c-strings into a function and have a table 6x6 printed out. However my code keeps compiling with an error. A segmentation fault. I understand that a seg fault is when the program looks for something that isn't there. I'm not sure how to fix this or how to alter this even after much research. Any suggestions would very much be appreciated.
Here's my code:
#include <iostream>
using namespace std;
void fillarrays(int labs[][6]);
void printarrays(int labs[][6]);
int main()
{
int labs[6][6];
fillarrays(labs);
printarrays(labs);
return 0;
}
void fillarrays(int labs[][6])
{
for(int row = 0; row<=6; row ++)
{
for(int col=0; col<=6; col++)
{
labs[row][col] = row;
}
}
}
void printarrays(int labs[][6])
{
cout << "Labs: " << '\t' << '\t' << endl;;
for(int rows=0 ; rows<6; rows++)
{
for(int cols=0; cols<6; cols++)
{
cout << '\t' << labs[rows][cols] << " ";
}
cout << endl;
}
}

labs[6][6] is an array with 6 rows first one is [0] and last one is [5], the same for cols, so change <=6 to <6 in fillarrays.
for(int row = 0; row<6;row ++) {
for(int col=0; col<6; col++) {
labs[row][col] = row;
}
}

for(int row = 0; row<=6;row ++) {
for(int col=0; col<=6; col++) {
labs[row][col] = row;
}
}
Look closely here - this fills a 7x7 array (indices 0 to 6 for rows and columns). But the array is only 6x6, so you're trying to write outside teh bounds of the array.
This is a reasonably common mistake; change the <=s to <s.

Related

Multiplication of a vector and a matrix in c++

I tried to multiply a vector by a matrix but I can't get it to work because the loop always stops at one line. But with no error code, I've tried different ways to write the code into the resulting vector but it doesn't work. The outputs are to control where the loop stops, it stops after res[i] += (A[i][k] * B[k]);.
This is the specific function to perform the vector & matrix multiplication, if you need all the code let me know.
void vector_matrix_multiplication(vector<vector<int>> A,vector<int> B, int col1, int row1, int row2, vector<int>& res) {
int row = row1;
if(row1 < row2)
row = row2;
for(int i = 0; i < row; i++) {
cout << "Loop 1 ";
cout << i << endl;
for (int k = 0; k < col1; k++) {
cout << "Loop 2 " << i << " " << k << endl;
res[i] += (A[i][k] * B[k]);
cout << "Loop 2?" << endl;
}
}
The output of the function (with input A = {{2,3},{4,5}} & B = {1,2} is:
Loop 1 0
Loop 2 0 0
#include <iostream>
#include <vector>
using namespace std;
void vectorinput(vector<int>& a, int col){
cout << "Vector: " << endl;
for(int i = 0; i < col; i++) {
int x;
cin >> x;
a.push_back(x);
}
}
void matrixinput(vector<vector<int>>& a, int row, int col){
cout << "Matrix: " << endl;
for(int i = 0; i < row; i++) {
vector<int> vector;
for(int j = 0; j < col; j++) {
int x;
cin >> x;
vector.push_back(x);
}
a.push_back(vector);
}
}
int main(){
vector<int> vector;
vector<vector<int>> matrix; //Matrix is read in separate function
int row1 = 0; //Number of rows of first matrix
int col1 = 0; //Number of columns of first matrix
int row2 = 0; //Number of rows second matrix (redundant in this case)
int col2 = 0; //Number of columns second matrix
matrixinput(matrix1, row1, col1);
vectorinput(vector2, col2);
int row = row1; //Matrix with number of columns "col1", rows "row" - in this case both are 2
if(row2 > row1)
row = row2; //Vector with number of rows "row2" - in this case 2
vector<int> resvector(row, col1);
vector_matrix_multiplication(matrix2, vector1, col2, row, col1, resvector);
for(int i = 0; i < row; i++) {
cout << resvector[i] << endl;
}
return 0;
}
I hope this clarifies the purpose of the program and the function. I tried to cut it down a little because I have a lot of useless code in it. (Plus I struggled to input the code at first, was not quite sure how the code block works - sorry ^^)
There are following three bugs in your code:
Since you use the following ctor of std::vector
explicit vector(size_type count,
const T& value = T(),
const Allocator& alloc = Allocator());
, the second argument of resvector must be zero.
row1, row2, col1 and col2 are all zero through the main function and thus the loop in vector_matrix_multiplication does not work.
We can also reduce these variables to row and col of the matrix as #n.m. suggests in the comments.
matrix1, matrix2, vector1 and vector2 are not defined.
In summary, the following minimally fixed version will work fine for you:
int main()
{
std::vector<int> vec;
std::vector<std::vector<int>> mat;
int row = 2; //Number of rows of matrix
int col = 2; //Number of columns of matrix
matrixinput(mat, row, col);
vectorinput(vec, col);
std::vector<int> resvector(row, 0);
// 5th argument is redundant as #n.m. suggested
vector_matrix_multiplication(mat, vec, col, row, col, resvector);
for(int i = 0; i < row; i++) {
std::cout << resvector[i] << std::endl;
}
return 0;
}
and welcome to StackOverflow! I suggest you using mathematical libraries for this kind of stuff. The reason is:
they are already tested by someone else
they are efficient and optimized to use advanced CPU features
they are easier to use
I've used two different libraries: glm and Eigen
If you want to build your own library for learning purpose I suggest you looking how these libraries are written (they're open source)

Pascal's Triangle by recursive function

int Pascal_Tri(int row , int col)
{
if (row==col || col==0)
return 1 ;
else
{
return Pascal_Tri(row-1,col)+Pascal_Tri(row-1,col-1);
}
}
there is a problem with this code and I can not discover it.
when I run it, the program stops working and no results disappear
C++11
#include <iostream>
#include <vector>
std::vector<int> pascal(int height, std::vector<int> curr)
{
for(int i=0; i<curr.size(); i++)
std::cout<<curr[i]<<" ";
std::cout<<std::endl;
if(height<=0)
return curr;
std::vector<int> newCurr(curr.size()+1,1);
for(int i=0; i+1 < curr.size(); i++)
newCurr[i+1] = curr[i] + curr[i+1];
return pascal(height-1,newCurr);
}
int main()
{
int row, col;
std::cin>>row>>col;
std::vector<int> rowPascal = pascal(row,std::vector<int>{1});
std::cout<< rowPascal[col];
}
With the driver function to test. I know it's not very efficient but it should do!
This will basically give you the number at a specific row ( from the top) and a specific col (from the left) in the pascal's triangle . (both zero indexed)
Given that it's unreasonably difficult to print the triangle without using loops, here is a solution that uses your purely recursive Pascal_Tri function to compute the numbers but prints them with a loop:
int rowsToPrint = 5;
for (int row = 0; row < rowsToPrint; ++row)
{
for (int col = 0; col <= row; ++col)
std::cout << Pascal_Tri(row, col) << ", ";
std::cout << std::endl;
}
Demo

How is my for-loop messing up?

I am having a problem with my for loops in this code that I've written. Everything runs fine except it does not catch the value for the 4th row in my string array ("Jill", "Jason", "Jim".)
I'm pretty sure the problem is happening in my function definition for 'Initialize' since the values for the final ID and final list of team members is not being caught by my vector. For reference, the output is fine up until the final TeamV element. I've tried messing with the indices a ton but I've hit a brick wall so-to-speak. Thanks in advance.
#include <vector>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
const int NUM_TEAMS = 4;
const int NUM_MEMBERS = 3;
struct TeamS {
int id;
string m[NUM_MEMBERS];
}TeamV, tempTeam;
void Initialize(vector <TeamS> & TeamV, const int id[],
const string m[][NUM_MEMBERS], int arraySize);
void printList(const vector <TeamS> & TeamV);
int main()
{
const int ID[NUM_TEAMS] = { 123, 321, 456, 789 };
const string MEMBERS[NUM_TEAMS][NUM_MEMBERS] =
{
{ "Sarah", "Joe", "John" },
{ "Chris", "Kevin", "James" },
{ "Tom", "Kim", "Emily" },
{ "Jill", "Jason", "Jim" }
};
vector<TeamS> TeamV;
Initialize(TeamV, ID, MEMBERS, NUM_TEAMS);
cout << TeamV[3].m[1];
printList(TeamV);
// not working on my installation at home -> system("pause");
cin.get();
}
void Initialize(vector<TeamS>& TeamV, const int id[], const string m[][NUM_MEMBERS], int arraySize)
{
//Resizes a TeamS vector and then modifies it's values to match the information provided
TeamV.resize(arraySize+1);
//iterate through teams
for (int i = 0; i < arraySize+1; i++)
{
TeamV[i].id = id[i];
//iterate through members of teams
for (int j = 0; j < NUM_MEMBERS; j++)
{
TeamV[i].m[j] = m[i][j];
}
}
}
void printList(const vector<TeamS>& TeamV)
{
cout << "**** Team List ****\n\n";
int teamVSize = TeamV.size();
for (int i = 0; i < teamVSize; i++)
{
cout << "Information for team " + to_string(i) << endl;
cout << "ID:\t" << TeamV[i].id << "\t";
for (int j = 0; j < NUM_MEMBERS; j++)
{
cout << TeamV[i].m[j] << "\t";
}
cout << endl;
}
}
Your for loop goes out of bounds of the array. Get rid of +1
for (int i = 0; i < arraySize; i++)
You pass in a 2D array with 4 rows, yet in your initialise() function you loop 5 times:
TeamV.resize(arraySize + 1); // Why plus 1?
//iterate through teams
for (int i = 0; i < arraySize + 1; i++) // Why plus 1?
{
TeamV[i].id = id[i];
//iterate through members of teams
for (int j = 0; j < NUM_MEMBERS; j++)
{
TeamV[i].m[j] = m[i][j]; // Because you loop four times on the
// last loop i = 4, which is outside the string
// array you passed, which has only 4 rows.
}
}
Zero index is the first, index i = 4 means the 5th row, you overrun the array you created, I get an std::bad_alloc exception.
If you leave out the + 1 from "arraySize + 1" it works fine.
By the way, the way it is now, it fills in correctly the 4 rows up until it throws the bad_alloc exception, so I don't understand why you said it leaves out the 4th row.

How to debug my C++ program?

I try to enter 2d array and to sum all numbers in one row. Then I convert that number to binary (8 bit) and to set it again in new 2d array. Here's my code. I get output in negative numbers and I expect binary number.
I input
1 2 3
4 5 6
7 8 9
And i want this output
00000110
00001111
00011000
i get
00000000
00000000
00000000
#include<iostream>
using namespace std;
int main()
{
int n,m,j,i;
int a[50][50],b[50][8],c[50];
cin>>n>>m;
for(i=0;i<n;i++)
{
c[i]=0;
for(j=0;j<m;j++)
{
cin>>a[i][m];
cin.ignore();
c[i]+=a[i][j];
}
}
for(i=0;i<n;i++)
for(j=0;j<8;j++)
{
b[i][j]=c[i]%2;
c[i]/=2;
}
for(i=0;i<n;i++)
{
for(j=0;j<8;j++)
{
cout<<b[i][j];
}
cout<<endl;
}
}
I attempted to revise your code but I soon realised that you were doing some weird unnecessary things so I just started fresh and here's what I've got for you:
#include <iostream>
#include <vector>
using namespace std;
void add_array(int arr1[], int arr2[], int arrLength, int ret[]) {
for(int i = 0; i < arrLength; i++) {
ret[i] = arr1[i]+arr2[i];
}
return;
}
void to_binary(int n, vector<int> *ret) {
while(n!=0) {
ret->push_back(n%2==0 ?0:1);
n/=2;
}
}
int main() {
int a[5] = {1,2,3,4,5};
int b[5] = {6,7,8,9,10};
int c[5];
add_array(a, b, 5, c);
cout << "A:" << endl;
for(int i = 0; i < 5; i++) {
cout << i << " : " << a[i] << endl;
}
cout << "B:" << endl;
for(int i = 0; i < 5; i++) {
cout << i << " : " << b[i] << endl;
}
cout << "C:" << endl;
for(int i = 0; i < 5; i++) {
cout << i << " : " << c[i] << endl;
}
vector<int> vec;
for(int i = 0; i < 5; i++) {
to_binary(c[i], &vec);
for(int j = 0; j < vec.size(); j++) {
cout << vec[j];
}
cout << endl;
vec.clear();
}
return 0;
}
I don't know how you were handling the adding of the two functions so I just wrote a really simple function there, I'll start with the parameters
int arr1[], int arr2[]
These are the two functions you'll be adding, simple.
int arrLength
This tells the function what the length of the two arrays is for the 'for loop'
int ret[]
Ret is the return array and is passed in so that it can be modified with the added arrays, now you could do that with either of the other two arrays but this is better practice especially if you want to reuse the other arrays later.
Now here's the function itself
for(int i=0;i<arrLength;i++){ ret[i]=arr1[i]+arr2[i];}
Here we loop through each position in the arrays and place them in the variable 'ret', this is the whole thing.
The function
void to_binary(int n, vector<int> *ret)
handles the decimal to binary using a vector for variable sizes, it's basically what you were doing just in a function.
In the function main we create the three arrays and call add_array with the necessary arguments, then we create the vector vec and then proceed to loop through the array c getting the binary number of each position and then since we stored the binary number in an int vector instead of a string we loop through the vector
for(int j = 0; j < vector.size(); j++)
We are using vector.size() to get the dynamic size of the vector, then we print out each binary digit and then print an endl and clear the vector for reuse.

C++ How to change the output on a new array

So I wrote a program that is supposed select the perfect squares from an array and put it into another array. Example: (2,4,13,5,25,66) and the second array(the result) should look like this (4,25)
My result looks like this (0,4,0,0,25,0) ...so its half good ...how to make it show only 4,25 ?
#include<iostream.h>
#include<math.h.>
int main()
{
int A[100],i,n,p,j;
cout << "Number of array elements=";
cin >> n;
for(i=1;i<=n;i++)
{
cout<<"A["<<i<<"]=";
cin>>A[i];
}
for(i=1;i<=n;i++)
{
p=sqrt(A[i]) ;
if(p*p==A[i])
A[j]=A[i];
else
A[i]=0;
cout << A[i] << " ";
}
return 0;
}
USING ONLY c++ basic commands...as i did
You need to keep a separate count of how many perfect squares you've found and use that to place your answers into an array of perfect squares:
int squares[???];
// ...
if(p*p==A[i]) {
squares[squaresFound]=A[i];
squaresFound++;
}
The problem now will be to decide how long the squares array should be. You don't know ahead of time how many squares you're going to get. Are you going to have it the same size as A and fill the rest with 0s? Or do you want the array of squares to be exactly the right size?
If you want it to be the right size, you're much better off using a std::vector:
std::vector<int> squares;
// ...
if(p*p==A[i]) {
squares.push_back(A[i]);
}
But I think your silly "only basic C++ commands" restriction will not allow you to do this.
You talk about a second array (the result), yet your code declares only one array! Additionally, you reference A[j], but your j has not be initialized.
You should declare another array B[100], initialize j to zero, and then use this code when you find a square:
int j = 0;
for (int i=0 ; i != n ; i++) {
int p = sqrt(A[i]);
if(p*p==A[i]) {
B[j++] = A[i];
}
}
Make another array, remove all occurrences of 0 from the resultArray and add non-0 to newArray.
OR
int j=0
if(A[i]==p*p)
squares[j++]=A[i];
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
int A[100];
int n;
cout << "Number of array elements = " << endl;
cin >> n;
for(int i = 0; i < n; i++)
{
cout << "A[" << i << "] = ";
cin >> A[i];
}
int B[100];
int cnt_sqr = 0;
for(int i = 0; i < n; i++)
{
int p = sqrt(A[i]);
if (p * p == A[i])
{
B[cnt_sqr++] = A[i];
}
}
for (int i = 0; i < cnt_sqr; i++)
{
cout << B[i] << ' ';
}
return 0;
}
Full code of that about what you were told above
If you do not want to modify your code you can write the following:
for(i=1;i<=n;i++)
{
p=sqrt(A[i]) ;
if(p*p==A[i])
{
cout << A[i] << " ";
}
}
It will print you only perfect squares.
If you want to copy elements to another array:
int squares[100] = {0}; // Assuming that all values can be perfect squares
int square_count = 0;
for(i=1;i<=n;i++)
{
p=sqrt(A[i]) ;
if(p*p==A[i])
{
squares[square_count++] = A[i];
}
}