How do I fix the size of my array? - c++

everyone. I am struggling with understanding why my numbers variable keeps outputting 1. I am trying to double the size anytime the number of elements is equal to the size of the array but I end up not getting anywhere near that part of my code.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int selection;
int size = 2;
// Initializing the array
int *dArray;
int v = 0;
int i, j, temp;
dArray = new int[size];
dArray[0] = 2;
dArray[1] = 3;
int numbers = sizeof(dArray) / sizeof(dArray[0]);
do {
// Printing the menu
cout << "1) Print Elements" << endl;
cout << "2) Add Element" << endl;
cout << "3) Delete Element" << endl;
cout << "4) Return Size" << endl;
cout << "5) Exit" << endl;
cout << "Enter your selection number: ";
cin >> selection;
switch (selection)
{
case 1:
// Outputting the elements
for (int i = 0; i < size-1; i++)
{
cout << dArray[i] << ", ";
}
cout << dArray[size - 1] <<endl;
cout << numbers << endl;
break;
case 2:
// Asking for another element
cout << "What number shall be put into the array? \n";
cin >> v;
if (numbers== size)
{
// If the size is too small...
int *nArray = new int[2 * size];
for (int i = 0; i < size; ++i)
{
nArray[i] = dArray[i];
}
delete[] dArray;
dArray = nArray;
// Finished creating a new array
cout << "Array size expanded to " << 2 * size << endl;
// Adding the element
dArray[size] = v;
size = 2 * size;
// Sorting the elements
for(i=0;i<numbers;i++)
{
for(j=i+1;j<numbers;j++)
{
if(dArray[i]>dArray[j])
{
temp =dArray[i];
dArray[i]=dArray[j];
dArray[j]=temp;
}
}
}
}
else
{
// Adding the element
dArray[size] = v;
size = 2 * size;
// Sorting the elements
for(i=0;i<numbers;i++)
{
for(j=i+1;j<numbers;j++)
{
if(dArray[i]>dArray[j])
{
temp =dArray[i];
dArray[i]=dArray[j];
dArray[j]=temp;
}
}
}
}
break;
}
} while (selection!= 5);
cin.get();
cin.ignore();
return 0;
}
Does anyone know why the sizeof function keeps acting this way?

This is not the size of your array. It's the size of a pointer, divided by the size of an int.
int numbers = sizeof(dArray) / sizeof(dArray[0]);
This is the size of the array in your program.
int numbers = size;

sizeof(dArray) gives you the size of dArray. dArray is defined as int *dArray, so its size is sizeof(int*). That doesn't change, regardless of what the pointer points to. That's different from an actual array; your size code would work correctly with int dArray[3];.
To get the size of the array, just use your size variable; that's the number of int objects that were allocated.
Even better, use std::vector<int>; its size() member function tells you how many elements it has.

int numbers = sizeof(dArray) / sizeof(dArray[0]);
Numbers is resolving to 1 because dArray is a pointer to the start of your array, not the array itself. When you call sizeof() you are getting the size of the pointer, not the array. On a 32 bit application, the pointer is 32 bits (4 bytes) and your first int is also 32 bits (4 bytes). So what this statement resolves to is
int numbers = 4 / 4;
leaving 1. If you instead declared an array of doubles then sizeof(dArray[0]) would be 8 but the size of the pointer would still be 4, so the statement would resolve to numbers = 4 / 8 = .5, but since numbers is an int it would just resolve to 0. So your code would still break, but in new exciting ways.
Interestingly enough, if you compiled this as a 64 bit application sizeof(dArray) would be 64 bits (8 bytes), so you would get numbers = 8 / 4 = 2 as you expected. Then you would double your array size and your code would break because numbers would resolve to 2 which would potentially be even more confusing, so be thankful you caught it now!
I agree with what others have said though. If you use a Vector you can just keep pushing values onto the end of it and let it worry about changing the size of the array!

Related

My print function does not print correctly when passing a 2d array, please tell me how to print all its values correctly. Is it my syntax?

code can be run/compiled here https://onlinegdb.com/9yhzLeVu3
this code will only print value 4 for all the values if tested on a 2x2 matrix
[1][2]
[3][4]
I believe its with the cout statement, I am fairly convinced it is saving the values to the matrix but, am not seeing it print correctly.
If could please tell me what I am not seeing? this syntax is very new to me, this program functions as functional programming but, is difficult once I start converting it to methods/functions.
#include <iostream>
using namespace std;
// Create a matrix based graph representation.
// It will need to support the following operations.
// Ask the user how many points there are. DONE
// Ask the user to label those points, ie "ABC", "XYZ", "C12"... DONE
// Define the matrix as a square matrix (2 dimensional array) based on the number of points, also keep an array of the labels. DONE
// Repeatedly ask the user to define edges between two points. Add these edges to the matrix. DONE
// Have a list method that will list out all of the edges in the graph.
// REFERENCE
// https://www.geeksforgeeks.org/how-to-access-elements-of-a-square-matrix/
// https://www.geeksforgeeks.org/comparison-between-adjacency-list-and-adjacency-matrix-representation-of-graph/
// https://www.cplusplus.com/reference/utility/make_pair/
// https://www.tutorialspoint.com/cplusplus-program-to-implement-adjacency-matrix
// https://stackoverflow.com/questions/2828648/how-to-pass-a-multidimensional-array-to-a-function-in-c-and-c
// https://www.techiedelight.com/pass-2d-array-function-parameter-cpp/
// https://www.tutorialspoint.com/Passing-two-dimensional-array-to-a-Cplusplus-function
// https://stackoverflow.com/questions/71907069/my-print-function-does-not-print-correctly-when-passing-a-2d-array-please-tell/71907317#71907317
// one possible implementation would be make pair to track the label for edge cout statement for user input
// Code is formatted to be best read with labels the size of 3 this is hard coded per implementation requirements.
int main()
{
// PROTOTYPE
void printMatrix(string *labelArray, int *matrix, int rowIndex, int columnIndex, int size);
int size ;
cout << "How many points would you like this to be. Points meaning -size- of matrix: ";
cin >> size;
// example 2x2 matrix
// A B
// A [][]
// B [][]
// determine size, and modulo to create matrix form
string label; // labeling convention for determining assignments
string labelArray[size]; // label containing array to track for printing and labeling purposes
int edgeYesOrNo;
int counter = 0;
cout << "Will now ask to label the points of graph matrix.\n";
int *matrix = new int[size * size]; // this is how to define a 2d array
int rowIndex; // these are to access individual elements
int columnIndex; // ^^
for(int i=0; i<size; i++)
{
cout << "Enter label: "; // enter the label here to insure that there is no redundancy
cin >> label;
labelArray[i] = label;
}
// Get the square matrix
cout << "Enter 1 for edge 0 for no edge" << endl;
for (rowIndex = 0; rowIndex < size; rowIndex++)
{
for (columnIndex = 0; columnIndex < size; columnIndex++)
{
cout << "Is there an edge to: " << labelArray[counter] << " and " << labelArray[columnIndex] << ": ";
cin >> edgeYesOrNo;
matrix[rowIndex * size + columnIndex] = edgeYesOrNo;
}
counter++;
}
printMatrix(labelArray, matrix, rowIndex, columnIndex, size);
delete[] matrix;
return 0;
}
// Display the matrix
void printMatrix(string *labelArray, int *matrix, int rowIndex, int columnIndex, int size)
{
cout << "The matrix is\n" << endl;
cout << " ";
for(int i=0; i<size; i++)
{
cout << labelArray[i] << " "; // To print the labels so its understandable
}
cout << endl;
for (rowIndex = 0; rowIndex < size; rowIndex++)
{
cout << labelArray[rowIndex] << " ";
for (columnIndex = 0; columnIndex < size; columnIndex++)
{
cout << matrix[rowIndex * size + columnIndex] << " ";
}
cout << endl;
}
return;
}
What do you think these lines are going to do:
matrix[size * size] = edgeYesOrNo;
cout << matrix[size * size] << " ";
I find it far more likely you need rowIndex * size + colIndex in both places.
I'll explain the difference. You've already allocated your array when you did this:
int *matrix = new int[size * size];
This is not a 2D array. It's a single dimension array. But that's okay. If size is four, size * size is 16, so you allocated space for 16 integers.
matrix[rowIndex * size + colIndex]
This is how I use it in both my places. What this means is you'll store them kind of like this:
[ 0][ 1][ 2][ 3]
[ 4][ 5][ 6][ 7]
[ 8][ 9][10][11]
[12][13][14][15]
That is, row 0, col 0 is thus in the 0'th index. row 1, col 1, is in the row * size + col location, or 5.
Does that make sense now?
C++ doesn't actually have 2D arrays. You can simulate it. This is one way to do so.
What you were doing was using (for size == 4) the 16th spot each time, which is actually one slot past the end. You were stepping on who knows what.

How to solve segmentation fault error C++

I'm writing a program that gets an array of integers and its logical size. When called it creates a new array containing only the positive numbers from the arrays.
Now, in order to do this I need to write a void type function takes the following parameters:
(int* arr, int arrSize, int** outPosArrPtr, int* outPosArrSizePTR)
I'm supposed to use the pointer int** outPosArrPtr to update the base address of the array containing the positive numbers, and the pointer outPosArrSizePtr to update the array's logical size.
now when I run my code on the xcode compiler the logical size gets updated to a very larger number. So, when I tried to run the program using the online gdb compiler I got the error "Segmentation fault."
From reading what Segmentation fault means I learnt that it means that I'm trying to access memory that "does not belong to me" or memory that is not in the call stack or in the heap portion of the program.
I tried to debug my code by seeing if I was referening any null pointers or see if I was referencing any dangling pointers but it seems like the problem is another one.
My code:
#include <iostream>
typedef int* IntArrPtr;
using namespace std;
int main() {
int arrSize;
int *ptrSize;
ptrSize = &arrSize;
cout << "How many integers will this array hold:\n ";
cin >> arrSize;
IntArrPtr a;
a = new int[arrSize];
fillArr(a, arrSize);
getPosNums4(a, arrSize,&a, ptrSize);
cout << "The new size in main is: " << arrSize << endl;
cout <<"The new array with positive integers is:\n";
/*for(int i =0; i<arrSize;i++) // this runs for a large size of arrSize
cout<< a[i] << " ";
cout<<endl; */
return 0;
}
void fillArr(int a[], int size){
cout << "Please enter " << size << " Integers separated by spaces\n";
cout << "Press enter when finished >\n";
int i;
for (i=0;i<size;i++)
cin >> a[i];
}
void getPosNums4(int* arr, int arrSize, int** outPosArrPtr,int* outPosArrSizePtr){
IntArrPtr newArr;
newArr = new int[arrSize];
int i;
int newIndx = 0;
outPosArrSizePtr = &newIndx;//initiliaze the pointer.
for(i=0;i<arrSize;i++){
if(arr[i] > 0){
newArr[newIndx] =arr[i];
newIndx++;
}
}
arrSize = newIndx;
*outPosArrSizePtr = arrSize;
cout << "The new size is of *outPosArrSizeptr is: " << *outPosArrSizePtr << endl;
for(int j=0;j<newIndx;j++)
outPosArrPtr[j] = &newArr[j];
delete []newArr;
newArr = NULL;
for(int i=0;i<newIndx;i++)
arr[i] = *outPosArrPtr[i];
}
an example When I run this program on Xcode:
How many integers will this array hold:
6
Please enter 6 Integers separated by spaces
Press enter when finished >
3 -1 -3 0 6 4
The new size is of *outPosArrSizeptr is: 3
The new array with positive integers is:
The new size in main is: 7445512
The program ended with exit code: 0
There are quite a few problems there, but the most crucial one is that assigning a value to a function's argument has no effect on the variable whose value you passed as the argument.
It doesn't matter that the argument is a pointer – there is nothing special about pointers.
What I think is happening is that your "copy back and forth" loop (I can't understand what it's supposed to do) in the function is writing outside the input array, causing undefined behaviour and, in this case, overwriting variables in main.
You're overcomplicating your function quite a bit. It should
Create a new array
Copy the positive values to this array
Update the output parameters with the address of this array and its (logical) size
(Think of out parameters as return values and handle them last.)
Something like this:
void getPosNums4(int* arr, int arrSize, int** outPosArrPtr,int* outPosArrSizePtr){
int* newArr = new int[arrSize];
int newIndx = 0;
for (int i = 0; i < arrSize; i++){
if (arr[i] > 0){
newArr[newIndx] = arr[i];
newIndx++;
}
}
*outPosArrPtr = newArr;
*outPosArrSizePtr = newIndx;
}
You should also not pass pointers to your "originals" for this function to modify, you should use new variables.
int main() {
int arrSize = 0;
cout << "How many integers will this array hold:\n ";
cin >> arrSize;
int* a = new int[arrSize];
fillArr(a, arrSize);
int * positives = nullptr;
int positiveSize = 0;
getPosNums4(a, arrSize, &positives, &positiveSize);
cout << "The new size in main is: " << positiveSize << endl;
delete [] a;
delete [] positives;
}
Modern C++ uses vector rather than manually allocating arrays. Manual allocation is prone to a variety of errors that are very difficult to debug.
The logic in your getPosNums4 method appears to be the trouble. If I understand the requirement, it should look for positive integers in the input array and copy them to a newly allocated output array. Over-allocating the output array is non-optimal but not an actual bug.
void getPosNums4(int* arr, int arrSize, int** outPosArrPtr,int* outPosArrSizePtr){
IntArrPtr newArr;
newArr = new int[arrSize];
int i;
int newIndx = 0;
for(i=0;i<arrSize;i++){
if(arr[i] > 0){
newArr[newIndx] =arr[i];
newIndx++;
}
}
*outPosArrSizePtr = newIndx;
cout << "The new size is of *outPosArrSizeptr is: " << *outPosArrSizePtr << endl;
*outPosArrPtr = newArr;
}
Note the the newly allocated array will need to be delete[] by the calling function or a memory leak will result.
Here is the same program in modern C++. Note that there is no use of new/delete which saves a lot of misery.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> integer_vector;
vector<int> positive_vector;
cout << "Type in integers. Type a Q to continue:" << endl;
int an_int;
while(cin >> an_int)
integer_vector.push_back(an_int);
for_each(integer_vector.begin(),integer_vector.end(),[&](int const& n){
if(n > 0)
positive_vector.push_back(n);
});
cout <<"The new array with positive integers is:\n";
for(auto const & element:positive_vector)
cout<< element << " ";
cout<<endl;
return 0;
}

C++ Passing values to 2D char array in a function

I am trying to use a function to sort through a char array full of words. The current issue I am having is that in my sortNames function I am getting the error, "expression must be a modifiable lvalue" at the part below
hold = nameArr[ii];
nameArr[ii] = nameArr[jj];
nameArr[jj] = hold;
I am guessing that its because I am trying to pass values through an array for some reason. I am struggling with understanding references and pointers and the such, and I imagine that is hurting me here as well. Any help with this would be fantastic, thank you in advance.
Here is my current code...
#include <iostream>
#include <string>
using namespace std;
char nameArr[20][15]; // array to store the 20 values
int val = 0; // variable to pass values to the array
int x = 0; // loop counter outside functions
//Function prototypes
void getNames(char (&nameArr)[20][15], int &val);
void sortNames( char(&nameArr)[20][15]);
//getNames Function
void getNames(char (&nameArr)[20][15], int &val)
{
int i = 0; // loop counter
cout << "Awesome, now lets input those names...\n" << endl;
for (i = 0; i < val; i++)
{
cout << "\nNAME " << i+1 << ": " << ' ';
cin >> nameArr[i];
}
cout << "\n\n\nThese are the names that you inserted:\n" << endl;
for (i = 0; i < val; i++)
{
cout << nameArr[i] << "\n" << endl;
}
}
// sortNames function
void sortNames( char(&nameArr)[20][15])
{
int n = 15; // max length of word
int ii = 0; // loop counter
int jj = 0; // other counter
string hold; // holding array
for (int ii = 0 ; ii < n ; ii++)
{
for (int jj = ii + 1; jj < n; jj++)
{
if (nameArr[ii] > nameArr[jj])
{
hold = nameArr[ii];
nameArr[ii] = nameArr[jj];
nameArr[jj] = hold;
}
}
}
}
int main()
{
cout << "NAME SORTER!\n\nPlease enter in the amount of names you wish to enter: " << ' ';
cin >> val;
getNames(nameArr, val);
cout << "\n\n\nAlright, lets sort now..." << endl;
sortNames(nameArr);
cout << "\nHere are the results:\n" << endl;
for (x = 0; x < val; x++)
{
cout << nameArr[x] << "\n" << endl;
}
system("pause");
}
Your main problem here is that you are trying to use an assignment operator on two fixed sized arrays, which isn't legal. Consider the following code:
int a[2] = {0, 0};
int b[2] = {1, 1};
a = b;
This gives the same error you are getting. On the lines you mentioned, you are doing the same thing with char[15] arrays.
To fix your problems, you either need to allocate your char array dynamically/work with the pointers, or a simpler solution would be to just change your char[][] array to a string[] array.
That being said, there are a lot of things you can clean up here:
You have a few variables declared globally that can just be defined in main or lower
You can declare loop counters inside the for loop instead of beforehand, as you do in the sortNames function
In sortNames you are declaring a few variables twice
I'll add a few things to dwcanilla's answer.
You will want to change your function prototypes and headers to something more like this:
void getNames(char ** & arr, int val);
void sortNames(char ** & arr);
What this means is that the function accepts a reference to an array of c-strings; that is, when you work with the array within the function you are modifying the actual array you passed and not just a copy. Also I think you'd be fine just passing the integer by value for getNames.
Second, global variables are generally a bad idea. Since you can pass the array reference directly to your functions you may want to declare nameArr and your other global variables inside main instead.
Third, in getNames you won't be able to use cin to assign your c-strings directly.
EDIT: This is a better way --
getting console input for Cstrings
Finally, the < operator doesn't work on c-strings the way you're using it in your sort function. Use strcmp() instead (and be sure to include the cstring header):
if(strcmp(arr[ii], arr[jj]) > 0)

Deleting duplicates in an array (C++)

I saw an older post on here asking how to do relatively the same thing, but their approach was different and i'm interested to know the hole in my program.
I am attempting to write a program that accepts characters into a 10 character length array. I want the program to evaluate the first array position and delete any duplicates it finds later in the array by identifying a duplicate and moving all of the values to the right of it to the left by one. The 'size' of the array is then decreased by one.
I believe the logic I used for the delete function is correct but the program only prints an 'a' for the first value and the fourth value in the array.
Any help would be greatly appreciated, here is my code:
#include <iostream>
using namespace std;
int letter_entry_print(int size, char array[10]);
int delete_repeats(int& size, char array[10]);
int final_array_print(int size, char array[10]);
int main()
{
char array[10];
int size = 10;
letter_entry_print(size,array);
delete_repeats(size,array);
final_array_print(size,array);
cout<<"\n";
system("pause");
}
int letter_entry_print(int size, char array[10])
{
int i;
for (i=0;i<size;i++)
{
cout << "Enter letter #" << i+1 << endl;
cin >> array[i];
cout << "\n";
}
cout << "\nYour array index is as follows:\n\n";
for (i=0;i<size;i++)
{
cout << array[i];
cout << " ";
}
cout <<"\n\n";
return 0;
}
int delete_repeats(int& size, char array[10])
{
int ans;
int loc;
int search;
int replace;
char target='a';
cout << "Enter 1 to delete repeats.\n\n";
cin >> ans;
if(ans==1)
{
for(loc=0;loc<size;loc++)
{
array[loc]=target;
for(search=1;search<(size-loc);search++)
{
if(target=array[loc+search])
{
for(replace=0;replace<(size-(loc+search));replace++)
{
array[loc+search+replace]=array[loc+search+replace+1];
array[size-1]=0;
size=(size-1);
}
}
}
}
}else(cout<<"\nWhy didn't you press 1?\n\n");
return 0;
}
int final_array_print(int size, char array[10])
{
cout<<"\nYour new index is as follows:\n\n";
int i;
for(i=0;i<size;i++)
{
cout<<array[i];
cout<<" ";
}
cout<<"\n";
return 0;
}
Ok, there are a few things about your code that look odd.
1) you repeat 10 all over the place to the point where there's no way you could resonably change it, but you also pass size along. Instead of making all your functions take arrays of 10 chars, consider just passing in a pointer to char, like:
int final_array_print(int size, char *array)
then you can change the size of your arrays more easily. There's no point in passing size everywhere if you're going to limit yourself forever to 10 items, and there's no good reason to pass arrays of 10 items around if you provide a size!
2) ok, so now you want to look for duplicates. Why do you overwrite the first element in your array with an 'a'?
char target='a';
...
array[loc]=target;
wouldn't you want to do it the other way around?
3) next, as #Mahesh points out, you probably want to use the comparison operator '==' rather than the assignment operator = when looking for duplicates that is:
if(target=array[loc+search])
should probably be
if(target == array[loc+search])
4) Next, dontbeafraidtousealittlewhitespacebetweenyourwordsandpunctuation.Itmakesitaloteasiertoidentifytypingmistakesandspellingerrors.
5) your loop to actually perform the replacement has incredibly complicated indices. It would be easier if you didn't start with replace = 0, but just start at replace = search + 1, try it out and perhaps you'll how much simpler all the rest of the indices become.

Double dimensional array to single dimensional array

I am just doing an experiment to put values in double dimensional array to a single dimensional array. Below is my code and result:
#include <iostream>
using namespace std;
int main()
{
int p[1][1];
int arrayA[4];
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
p[i][j] = i+j;
}
}
int *a = &(p[0][0]);
for(int k=0;k<4;k++)
{
arrayA[k] = *a;
cout << "*a: " << *a << endl ;
cout << "array[k] :" << arrayA[k] << endl;
cout << "a: " << a << endl;
cout << "---------------------------" << endl;
a++;
}
system("PAUSE");
}
and the result is:
But I have no idea why it missed the value of p1[0], which value should be 1. But instead, I got a weird number where it is from. Because this is weird to me that I can put the last number in the double dimensional array to the single dimensional array but not the number before.
So I hope somebody can tell me what happen to me code or my method of thinking. Thank you.
This results in an out of bounds on array p:
int p[1][1];
int arrayA[4];
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
p[i][j] = i+j;
}
}
Indexes on arrays run from 0 to N - 1, where N is the size of the array.
The problem is that you wrote:
int p[1][1];
Remember that in C, and in C++, the number on elements for dimensions is the true number that you mean the vector or matrix to have. However, their indexes run from 0 to n-1 (where n is the number you wrote). So your declaration of p should be:
int p[2][2];
instead.
Hope this helps.
You wrote int p[1][1] but I think you meant int p[2][2].