How to add a new row everytime a user asks to? - c++

My task is to create a function that adds a row to a 2d Array everytime that a user asks to. For simplicity, I have a default row value to start with and a column value that should be kept. This task can be referenced to a bookshelf. Once a certain amount of books or on that row of the bookshelf, then move to the next row and begin placing books there.
Additionally, how should I free the program once a new row is created?
I am a new programmer and do apologize if my question sounds dumb. Thanks in advance!
Attached is what I have so far.
#include <iostream>
#include <string>
using namespace std;
int **addRows(int row, int cols, int values)
{
// Declare a 2d Array
int **twoD;
twoD = new int *[row];
// Fill each row with a column
for (int i = 0; i < row; i++)
{
twoD[i] = new int[cols];
}
// Fill each row, column with value
for (int i = 0; i < row; i++)
{
for (int j = 0; j < cols; j++)
{
twoD[i][j] = values;
}
}
// Return the 2d array
return twoD;
}
int main()
{
int **twoD;
int row = 1;
int cols = 5;
int values = 1;
int userInput;
// Call the function with 3 parameters by assigning the returned array to twoD
twoD = addRows(row, cols, values);
cout << "Do you want to add a row? 1 for yes, 0 for no, -1 to exit";
cin >> userInput;
while (userInput != -1)
{
if (userInput == 1)
{
twoD = addRows(row, cols, values);
}
else
{
// Print out each value in the 2d Array to console
for (int i = 0; i < row; i++)
{
for (int j = 0; j < cols; j++)
{
cout << twoD[i][j];
}
cout << endl;
}
// Free the memory
for (int i = 0; i < row; i++)
{
delete (twoD[i]);
}
delete (twoD);
}
cout << "Do you want to add a row? 1 for yes, 0 for no, -1 to exit";
cin >> userInput;
}
}

Your code is missing the following lines:
//remove memory allocation of array of columns for each row
for (int i = 0; i < row; i++) {
delete[] twoD[i];
}
//remove memory allocation of array of rows
delete[] twoD;
//increase the amount of rows in our new twoD matrix
row++;
in this section:
if (userInput == 1)
{
//right here
twoD = addRows(row, cols, values); //call addRows to generate the new twoD matrix with the increased row count
}

Related

stack around a variabe corrupted plus programs stops after inputting certain value c++

My program is meant to generate a dynamic 2d array then sort then transpose the array(swtitching columns and rows) My problem is when i input a certain value(7) for the rows and columns a stack around the variable indices becomes corrupted furthermore my code starts generating numbers that make no since i think its because it some is out of bounds please help me im relalitvely new to c++
//
// C++ program template
//
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
void init_array(int ** array_in, int rows, int cols, int list[]);
void print_array(int ** array_in, int rows, int cols);
void selection_sort(int array_in[], int elements);
int ** transpose(int ** array_in, int ** array_out, int rows, int cols);
const unsigned int SIZE = 4000;
int count1 = 0;
int main(void)
{
int rows = 0, cols = 0, j = 0, k = 0;
int**numbers = nullptr;
int**arraytranspose = nullptr;
cout << "Enter rows and columns" << endl;
cin >> rows >> cols;
int length = rows * cols;
int list[4000] = { 0 };
numbers = new int*[rows];
arraytranspose = new int*[rows];
for (k = 0; k < cols; k++)
{
numbers[k] = new int[cols];
arraytranspose[k] = new int[cols];
}
// initialize the array with unique values
init_array(numbers, rows, cols, list);
print_array(numbers, rows, cols);
selection_sort(list, count1);
int count3 = 0;
for (int count2 = 0; count2 < 3999; count2++) {
for (int i = 0; i < rows; i++)
{
for (int c = 0; c < cols; c++)
{
if (list[count2] != 0)
{
numbers[i][c] = list[count2];
}
count2++;
}
}
}
print_array(numbers, rows, cols);
cout << endl << endl;
print_array(transpose(numbers,arraytranspose,rows,cols), rows, cols);
system("pause");
return 0;
}
void selection_sort(int array_in[], int elements)
{
int index = 0, smallest = 0, hold = 0, count = 0, location = 0;
for (index = 0; index < SIZE - 1; index++) // Loop to control number of passes
{
smallest = index;
// Find the index of the smallest element
for (location = index + 1; location < SIZE; location++)
{
if (array_in[location] < array_in[smallest])
{
smallest = location;
} // End If
} // End Inner for loop
hold = array_in[smallest];
array_in[smallest] = array_in[index];
array_in[index] = hold;
count++; // Count number of swaps
}
cout << "There were " << count << " element exchanges during the sort. " << endl << endl;
return;
}
void init_array(int ** array_in, int rows, int cols, int list[])
{
int j = 0, k = 0, value = 0;
int indices[4000] = { 0 };
count1 = 0;
while (j < rows)
{
k = 0;
while (k < cols)
{
value = rand() & 4000;
if (indices[value] != 1)
{
array_in[j][k] = value;
indices[value] = 1;
list[count1] = array_in[j][k];
k++;
count1++;
}
}// end while
j++;
}
return;
}
void print_array(int ** array_in, int rows, int cols)
{
int j = 0, k = 0;
for (j = 0; j < rows; j++) {
for (k = 0; k < cols; k++) {
cout << setw(5) << array_in[j][k];
}
cout << endl;
}
return;
}
int** transpose(int ** array_in, int ** array_out,int rows, int cols)
{
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
array_out[r][c] = array_in[c][r];
}
}
return array_out;
}
numbers = new int*[rows];
arraytranspose = new int*[rows];
This allocates memory for a pair of arrays, an array of rows values.
Immediately afterwards:
for (k = 0; k < cols; k++)
{
numbers[k] = new int[cols];
arraytranspose[k] = new int[cols];
}
And this set the first cols values in these arrays, but they are rows values in size. So, if rows is less than cols, this results in memory corruption and undefined behavior, as the shown code writes to values of the array that do not exist.
This is the first obvious flaw in the shown code that's obvious from a cursory inspection, but it's likely there are other similar flaws as well; they generally result from unsafe programming practices like the ones shown here, like manual memory allocation, and lack of bounds checking. Modern C++ code offers plenty of safe programming practices, like using std::vectors to manage dynamically-sized arrays, and iterators.
Simply fixing this specific bug will be merely a bandaid, even if it turns out to be the only bug fix. Your real, long-term fix is to rewrite this entire code, and start using modern C++ containers, containers, and algorithms, which, when used correctly, will eliminate most opportunities for this entire class of bugs.

Passing dynamically allocated 2D char array causes segmentation error?

I am having trouble using a function.
I have two functions.
createTwoDArray: prompts user for row and column sizes, creates a new 2D array and returns it while also modifying the row and column variables passed to it.
printTwoDArray: should take in a 2d array and print everything. However, when calling this function, segmentation fault occurs immediately. Not one line of code inside the function is called even.
Thank you :)
int column, row;
char** createTwoDArray(int& column, int& row) {
int min, max, i, j;
cout << "\nPlease enter row size:";
cin >> i;
row = i;
cout << "\nPlease enter column size:";
cin >> j;
column = j;
char** dynamicArray2 = new char*[column];
for(i = 0; i < row; i++) {
dynamicArray2[i] = new char[column];
for(j = 0; j < column; j++) {
dynamicArray2[i][j] = '\0';
}
}
return dynamicArray2;
}
void printTwoDArray(char** array, int row, int column) {
//
}
//
char** array2 = new createTwoDArray(column, row)
printTwoDArray(array2, column, row); //this causes the segmentation error
//
There are two errors: 'column' was used to allocate rows, and row and column were mixed up when calling printTwoDArray().
Here is the fixed code. It runs fine in Visual C++.
#include "pch.h"
#include <iostream>
int column, row;
char** createTwoDArray(int& column, int& row) {
int min, max, i, j;
std::cout << "\nPlease enter row size:";
std::cin >> i;
row = i;
std::cout << "\nPlease enter column size:";
std::cin >> j;
column = j;
// *** Use row, not column to allocate the number of rows.
char** dynamicArray2 = new char*[row];
for (i = 0; i < row; i++) {
dynamicArray2[i] = new char[column];
for (j = 0; j < column; j++) {
dynamicArray2[i][j] = '\0';
}
}
return dynamicArray2;
}
void printTwoDArray(char** array, int row, int column) {
printf("\nPrinting %d rows:\n\n", row);
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
printf(" %2d", array[i][j]);
}
printf("\n");
}
}
int main()
{
//
char** array2 = createTwoDArray(column, row);
// Pass row and column in the right order!
printTwoDArray(array2, row, column);
//
return 0;
}

Sorting 2D Dynamic Array C++

I am trying to sort a two dimensional dynamic array when row 1 is for product ID and row 2 is for the product price. I want to sort by product ID, and have the results displayed formatted with width of 5. Here is my code:
This section is fine and does what I am looking for:
void readData (int**, int, int);
void printData(int**, int, int);
void sortbyPartID(int**, int, int);
int main()
{
int index;
int **PriceSheet, rows, columns;
cout << "Enter the number of Products, and then the number of values associated with the products: ";
cout << "For default values, enter 5 (FIVE ITEMS, and enter 2 (TWO Values: ID and PRICE). ";
cin >> columns >> rows;
cout << endl;
PriceSheet = new int* [rows];
for (int row = 0; row < rows; row++)
PriceSheet [row] = new int[columns];
readData (PriceSheet, rows, columns);
cout << endl;
printData(PriceSheet, rows, columns);
sortbyPartID(PriceSheet, rows, columns);
return 0;
}
void readData (int **p, int rowSize, int colSize)
{
for (int row = 0; row < rowSize; row++)
{
cout << "Row ZERO is the Product ID and Row 1 is the Product Price\n";
cout << "Enter " << colSize << " numbers for the row number " << row << ": ";
for (int col = 0; col < colSize; col++)
cin >> p[row][col];
cout << endl;
}
}
void printData (int **p, int rowSize, int colSize)
{
cout << "\n\nThese are the Products IDs and Prices as entered in the system:\n";
for (int row = 0; row < rowSize; row++)
{
for (int col = 0; col < colSize; col++)
cout << setw(5) << p[row][col];
cout << endl;
}
}
THIS SECTION IS WHERE I NEED HELP
It reads correctly and prints the unsorted array also correctly, but I cannot figure out a way to sort the array. Specifically speaking, I need help on the void sortbyPartID function. I would like to use bubble sort, and I cannot figure out how to get this function to work. Any help with the sorting function/algorithm would be greatly appreciated.
void sortbyPartID (int **p, int rowSize, int colSize)
{
int swap = -1;
int end = colSize;
int sortedID = **p;
cout << "\n\nThese are the Products sorted Products IDs:\n";
for (int counter = colSize -1; counter >= 0; counter --)
for (int index = 0; index < end ; index ++)
{
if (sortedID[index] > sortedID[index + 1])
{
swap = *sortedID[index + 1];
sortedID[index + 1] = sortedID[index];
*sortedID[index] = swap;
}
}
for(int index = 0; index < end; index++)
{
cout << sortedID[index] << ", ";
}
cout << endl;
end --;
}
When I run, I get some weird results on the last section. Maybe I am missing something simple, not sure.
We can also perform this using do-while as follows:
bool isSwaped;
do
{
isSwaped = false;
for (int index = 0; index < end - 1 ; ++index)
{
if (p[index][0] > p[index + 1][0])
{
int swap = p[index + 1][0];
p[index + 1][0] = p[index][0];
p[index][0] = swap;
isSwaped = true;
}
}
} while (isSwaped);
You can simplify the entire thing by using objects. Objects allow you to handle the related data in a sane fashion. Also highly recommend are vectors instead of C arrays.
struct Product {
int id;
int price;
vector<int> others;
}
You can then store your products in vector<Product> my_products; and then sorting everything with
std::sort(my_products.begin(), my_products.end(),
[](const Product& a, const Product& b) { return a.id < b.id; });
You can keep the existing input/output format, but place the values in the right place. This way it's almost impossible to mess up the attributes and everything is easy to work with.
int sortedID = **p; is not what you want, and should be removed. (I think you wanted int** sortedID = p;)
Your bubble-sort should be something like:
for (int counter = colSize -1; counter >= 0; --counter)
{
for (int index = 0; index < end - 1 ; ++index)
{
if (p[index][0] > p[index + 1][0])
{
// std::swap(p[index], p[index + 1]);
int* swap = p[index + 1];
p[index + 1] = p[index];
p[index] = swap;
}
}
}
Live Demo

Dereferencing Pointer to Pointer

I'm trying to run through a 2-dimensional array and update values using a pointer to pointer to int.
Swap function:
void foo(int ** vacancies, int **transfers, int transfer)
{
for (int i = 0; i < transfer; i++)
{
(*transfers[i]) = 0;
(*vacancies[i]) = 2;
}
}
Declaration:
int ** vacancies = new int*[getVacancies(grid)];
int ** transfers = new int*[transfer];
Function call:
foo(vacancies, transfers, transfer);
Unfortunately this doesn't seem to actually update any values, is there something I need to change? Thanks!
Edit:
getVacancies(vacancies, grid, transfer);
getTransfers(transfers, grid, transfer);
void getVacancies(int ** vacancies, int grid[][ROW], int vCount)
{
for (int i = 0; i < vCount; i++)
{
for (int row = 0; row < ROW; row++)
{
for (int col = 0; col < COL; col++)
{
if (grid[col][row] == 0)
{
vacancies[i] = &grid[col][row];
}
}
}
}
}
And the same for getTransfers.
Edit 2:
void getVacancies(int ** vacancies, int grid[][ROW], int vCount)
{
int i = 0;
for (int row = 0; row < ROW; row++)
{
for (int col = 0; col < COL; col++)
{
if (grid[col][row] == 0)
{
vacancies[i] = &grid[col][row];
i++;
}
}
}
}
You have allocated only "one dimension". Those int* elements should point to arrays of int or just ints. Dereferencing these uninitialized pointers is undefined behavior.
I think this is how you need to initialize your array. You shouldn't loop through vacancies, because that will fill each element with a pointer to the same element of grid (the last vacant one). Instead, you just want to loop through grid, and add each vacant element to the next entry in vacancies.
I've also changed the function to return the number of elements that were filled in. Alternatively, you could initialize vacancies to nullptr in each element, and test for this when looping through it later.
int getVacancies(int ** vacancies, int grid[][ROW], int vCount)
{
int i = 0;
for (int row = 0; row < ROW; row++)
{
for (int col = 0; col < COL; col++)
{
if (grid[col][row] == 0)
{
if (i >= vCount) { // Prevent overflowing vacancies
return i;
}
vacancies[i++] = &grid[col][row];
}
}
}
return i;
}
Allocate a two dimensional array like this (see How do I declare a 2d array in C++ using new?):
int** twoDimensionalArray = new int*[rowCount];
for (int i = 0; i < rowCount; ++i) {
twoDimensionalArray[i] = new int[colCount];
}

Replacing values in a 2D array

I have to create a program that allows a user to fill in a (partial) Latin Square of order 4. You can use 0's to represent empty cells. The user will give the number to place, the row and column. The number should only be placed if it does not violate the properties of a partial Latin square and it shouldn't rewrite numbers that have already been placed.
I have an matrix that is outputting all zeroes now. So next I have to replace each of these values by what the user is inputting. The problem is I don't know how to do this.
Here is my code:
#include <iostream>
using namespace std;
const int ORDER = 4;
void fill (int m[], int order);
void outputMatrix (int m[], int order);
void replaceValue (int m[], int order, int n, int row, int column);
int main(){
int matrix[ORDER];
int row;
int column;
int n;
fill (matrix, ORDER);
outputMatrix (matrix, ORDER);
do {
cout << "Enter the number to place, the row and the column, each seperated by a space: ";
cin >> n;
cin >> row;
cin >> column;
}while (n > 0 || n <= ORDER);
if (n <= 0 || n >= ORDER){
cout << "Thank you";
cout << endl;
}
return 0;
}
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
void outputMatrix (int m[], int order){
int c = 0;
for (int i = 0; i < order*order; i++){
c++;
cout << m[i] << ' ';
if (c == order){
cout << endl;
c = 0;
}
}
cout << endl;
}
void replaceValue (int m[], int order, int n, int row, int column){
for (int i = 0; i < order; i++){
m[order] = m[row][column];
m[row][column] = n;
}
}
How do I replace values in a Matrix in C++?
If you have a matrix, matrix[row][col] = value; would do the trick. However, I see that you allocate a single array. Make sure you look at this.
EDIT:
I looked closer at you code and you are doing some things wrong.
First:
matrix[ORDER]
will create a single array of ORDER values. If you want and ORDER by ORDER matrix try:
matrix[ORDER][ORDER]
Second:
You are calling:
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
with an of size 4 and order == 4. This will loop outside the array and give you problems.
Try something like:
matrix[ORDER][ORDER];
for (int row = 0; row != ORDER; ++row)
{
for (int col = 0; col != ORDER; ++col)
{
matrix[row][col] = 0;
}
}
Hope this helps.
You can't really write arr[i][j] if arr is defined as arr[]. There's no information about the length of the row (how many columns there are).
You could use arrays of type arr[][4], and write your functions like so:
// The & is to pass by reference.
void print(int (&arr)[][4], int length)
{
for(int i = 0; i < length; i++) {
for(int j = 0; j < 4; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
But in my opinion for a low-order multidimensional array like this one, using a typedef for a vector of vectors is the better option:
typedef vector<vector<int> > Matrix;
void print(Matrix& arr)
{
for(int i = 0; i < arr.size(); i++) {
for(int j = 0; j < arr[i].size(); j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
In either case, writing arr[i][j] = k will behave as you expect.
The easiest way to clear/zero your matrix is that:
memset( &matrix, 0, sizeof(matrix));
;-)