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;
}
Related
This question already has answers here:
Return array in a function
(20 answers)
Closed 4 years ago.
I'm really confused on the theory behind this. Not sure how to return the array from my isAscending function so i can print out in the main.
#include <iostream>
#include <string>
using namespace std;
// Implement printArray here
void printArray(int array[], int n){
for (int i = 0; i < n; ++i )
cout << array[i] << endl;
};
// Implement isAscending here
int isAscending(int array[], int n){
for(int i = 0; i <= n; ++i){
for(int j = 0; j <= n; ++j){
if(array[i] > array[j+1]){
int temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
}
}
}
return printArray(array, n);
};
// DO NOT CHANGE MAIN FUNCTION BELOW
int main() {
int myarray[100];
cout << "Enter number of integers : ";
int n;
cin >> n;
cout << "Enter " << n << " integers" << endl;
for (int i = 0; i < n; i++)
cin >> myarray[i];
cout << "Contents of array : ";
printArray(myarray, n);
cout << "Output of isAscending: " << isAscending(myarray, n) << endl;
}
Should I use pointers to pass the elements in the array i am stuck.
The short answer is you don't. When you pass an array to a function, you're actually just passing a pointer to the first element (the array decays to a pointer when you pass it as an argument). This means that if you modify the array in the function, you're modifying the original array and not a copy. Therefore, your isAscending() function will bubble sort the array you called it on and it does not need to return anything.
Just a side note, it seems like the assignment simply wants you to check if an array is ascending, instead of sorting it. In that case, isAscending() should return a bool.
If you need a function to return an array, you can't just pass a pointer to the first element since the array goes out of scope as soon as the function returns. You could dynamically allocate the array, but that just creates a bunch of new problems. Another way might be to return the pointer to the first element of the array passed to it as an argument like this, but there isn't much point in doing that since the caller already has access to the array.
The best way would be to use something like std::array or std::vector, which you can return by value just like any other variable. I would also recommend getting a good book.
(I provided this answer besides flagging as a duplicate since I thought the answer of the duplicate question was not complete enough and might mislead someone into trying to return a pointer to a local array)
I am trying to output the values present in the array, that are accepted during runtime, onto the console. But when I run this program I get the 5 values in the array as the last value only.
For example: if i give 0 1 2 3 4 as the five values for this program then the output is shown as 4 4 4 4 4.
#include "stdafx.h"
#include<iostream>
using namespace std;
int main()
{
int arrsize = 5;
int *ptr = new int[arrsize];
*ptr = 7;
cout << *ptr << endl;
cout << "enter 5 values:";
for (int i = 0; i < arrsize; i++)
{
cin >> *ptr;
cin.get();
}
cout << "the values in the array are:\n ";
for (int i = 0; i < arrsize; i++)
{
cout << *ptr << " ";
}
delete[] ptr;
cin.get();
return 0;
}
Both of your loops:
for (int i = 0; i < arrsize; i++)
...
loop over a variable i that is never used inside the loop. You are always using *ptr which refers always to the first element of the dynamically allocated array. You should use ptr[i] instead.
A part from that, dynamic allocation is an advanced topic. I'd recommend sticking with simpler and more commonly used things first:
std::cout << "Enter values:";
std::vector<int> array(std::istream_iterator<int>(std::cin), {});
std::cout << "\nThe values in the array are:\n";
std::copy(begin(array), end(array), std::ostream_iterator<int>(std::cout, " "));
Live demo
Following issues I think you could tackle:
The first include can be omitted I think. Your code works without that.
You use cin.get(), not sure why you need that. I think you can remove that. Even the one at the very end. You could put a cout << endl for the last newline. I am using Linux.
And use ptr like an array with index: ptr[i] in the loops as mentioned in the other answer. ptr[i] is equivalent to *(ptr+i). You have to offset it, otherwise you're overwriting the same value (that is why you get that result), because ptr points to the first element of the array.
P.S.: It seems that if you're using Windows (or other systems) you need the cin.get() to avoid the console to close down or so. So maybe you'd need to check it. See comments below.
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.
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].
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!