Pass subarray to function - c++

I have a function to which I need to pass an array.
But I don't want to pass the entire array (e.g., valid indices from array[0] to array[size-1]), but a subarray (e.g., valid indices starting at array[5] to array[size-1]).
Is there a way to do that in C++?

You can transfer array to function parameter below
void Foo(int* arr, int length);
//call Foo
Foo(&a[0], length); //or
Foo(a, length);
you can also transfer a certain range of array.
Foo(&a[1], length);
Foo(a + 1, length);
Just, simple code.
#include <iostream>
void Print(int* arr, int length)
{
for(int i=0; i < length; i++)
{
std::cout << *(arr + i) << ", ";
}
std::cout << std::endl;
}
int main()
{
int a[5] = {1,2,3,4,5};
//type A
Print(&a[0], sizeof(a)/sizeof(int)); //print all element of a
Print(&a[1], 3); //print 2,3,4
//type B
Print(a, sizeof(a)/sizeof(int)); //print all element of a
Print(a + 1, 3); //print 2,3,4
getchar();
return 0;
}

Quoted comment by n.m.:
You cannot pass an array to a function. When you try to, you actually pass the address of the first element of the array. If you need a subarray that starts at 5, you just pass the address of the fifth elements. You shouldn't be using C-style arrays anyway. Use std::vector and iterators, this is the C++ way.
As indicated, you can add an offset to the array base pointer (and subtract from the passed arraysize accordingly).
Or pass begin and end (one past the end) pointers of the array to the function to achieve an "iterator-style" implementation.
But as you are programming C++, please consider to use std::vector.
Example:
#include <iostream>
void foo(int arr[], int size) {
for (int i = 0; i < size; i++)
std::cout << arr[i] << ' ';
}
void bar(int* begin, int* end) {
while (begin != end)
std::cout << *begin++ << ' ';
}
int main() {
int arr[] = {0,1,2,3,4,5,6,7,8,9};
int size = sizeof(arr)/sizeof(*arr);
// pass entire array
foo(arr, size);
//bar(arr, arr+size);
std::cout << '\n';
// pass array starting at index 5
foo(arr+5, size-5);
//bar(arr+5, arr+size);
std::cout << '\n';
}
The output is:
$ g++ test.cc && ./a.out
0 1 2 3 4 5 6 7 8 9
5 6 7 8 9

Related

How is this array is altering its value? [duplicate]

This question already has answers here:
Are passing char array by (char* ar) and (char ar[ ]) same? c++ [duplicate]
(1 answer)
What is array to pointer decay?
(11 answers)
Closed 1 year ago.
This is a post from https://www.geeksforgeeks.org about reversing an array.
In the rvereseArray() function, array is not using any pointer. But still in the main() function, when the rvereseArray() function is called and the arr is passed, it is able to alter the value. how?
// Iterative C++ program to reverse an array
#include <bits/stdc++.h>
using namespace std;
/* Function to reverse arr[] from start to end*/
void rvereseArray(int arr[], int start, int end)
{
while (start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
/* Utility function to print an array */
void printArray(int arr[], int size)
{
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
/* Driver function to test above functions */
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6};
int n = sizeof(arr) / sizeof(arr[0]);
// To print original array
printArray(arr, n);
// Function calling
rvereseArray(arr, 0, n-1);
cout << "Reversed array is" << endl;
// To print the Reversed array
printArray(arr, n);
return 0;
}

returning an array address from function in c++ issue

i'm new to programming , this code gives me syntax error in line => int *result = apply_all(array1,5,array2,3) this is the error: expected primary-expression before '}' token|
i'm trying to write function called apply_all expects 2 arrays of integers and their sizes and dynamically allocates a new array of integers whose size is the product of 2 array sizes.
the function should loop through the 2nd array and multiple each element accross each element of array 1 and store the product in newly created array. the function is returning a pointer of to the newly allocated array.
also i wrote a function which is print to display the 1st & 2nd & newly array.
#include <iostream>
using namespace std;
//function prototype
int *apply_all(int *array1 ,int size1,int *array2,int size2);
void print(int *array,int size);
int main()
{
int array1[] {1,2,3,4,5};
int array2[] {10,20,30};
cout << "Array 1:";
print(array1,5);
cout << "Array 2:";
print(array2,3);
int *result = apply_all(array1,5,array2,3);
cout << "Result : ";
print(result,15);
delete [] result;
return 0;
}
int *apply_all(int *array1 ,int size1,int *array2,int size2)
{
int *result {nullptr};
result = new int[size1 * size2];
for (int i{0};i<size2;i++)
for(int j{0};j<size1;j++)
*(result[i*5+j]) = *(array1[i])**(array2[j]);
return result;
}
void print(int *array,int size)
{
for(auto num:array)
cout << num << endl;
}
On this line:
*(result[i*5+j]) = *(array1[i])**(array2[j]);
since result[i*5+j] gives you an int, you are trying to dereference an int, which is not possible.
You just need to do:
result[i*5+j] = array1[i] * array2[j];
Also, in print, your range-for loop won't work with a pointer. You need to do:
for(int i = 0; i < size; ++i)
cout << array[i] << endl;
Also, in apply_all, your loop bounds are incorrect. i needs to go till size1, and j needs to go to size2.
Here's a demo.
Since you are new, a simple work around would be creating an array with buffer space to store your results in and passing the pointer for this into apply_all. You could then write to this array which (being declared in main) should be very easy to access and cause few errors and use a c-string like ending to know when your results are over and to stop printing from the array (c-strings end with a value of 0 so that programs don't read unrelated memory). eg:
int buf[99];
apply_all(array_1, size1, array_2, size2, buf, size3);
for (int x = 0; buf[x] != end of buf var; x++;)
{
print(buf[x])
}
and
apply_all()
{
buf[start-end] = whatever you want;
buf[end + 1] = some variable that won't appear in buffer; //max int size?
}

Function to delete an element from an array not working

I wanted to write a function which upon being called deletes an element from an array given that the parameters passed in the deleteArray function were the array, its length and the value of the element to be deleted.
Tried breaking out of the for loop while transversing through the array if the element was found and then tried using i's value in another for loop to replace the current elements with their next element.
like array[j] = array[j + 1]
Here is the code:
#include <iostream>
using namespace std;
void deleteElement(int[], int, int);
int main() {
int array1[] = { 1, 4, 3, 5, 6 };
int length = sizeof(array1) / sizeof(array1[0]); //For length of array
deleteElement(array1, length, 4);
cout << "\nIn main function\n";
for (int i = 0; i < length; i++) {
cout << array1[i];
}
return 0;
}
void deleteElement(int array2[], int length, int element) {
int i = 0;
for (int i; i < length; i++) {
if (array2[i] == element) {
for (int j = i; j < length; j++) {
array2[j] = array2[j + 1];
}
break;
}
}
if (i == (length - 1)) {
cout << ("Element doesn't exist\n");
}
cout << "Testing OP in deleteElement\n";
for (int i = 0; i < length; i++) {
cout << array2[i];
}
}
Expected:
Testing OP in deleteElement
14356
In main function
1356
Actual:
Testing OP in deleteElement
14356
In main function
14356
The problem is rather silly:
At the beginning of deleteElement(), you define i with int i = 0;, but you redefine another variable i as a local index in each for loop. The for loop introduces a new scope, so the int i definition in the first clause of the for loop defines a new i, that shadows the variable with the same name defined in an outer scope.
for (int i; i < length; i++) {
And you do not initialize this new i variable.
There are 2 consequences:
undefined behavior in the first loop as i is uninitialized. The comparison i < length might fail right away.
the test if (i == (length - 1)) { tests the outer i variable, not the one that for iterated on. Furthermore, the test should be if (i == length) {
There are other issues:
the nested for loop iterates once too many times: when j == length - 1, accessing array[j + 1] has undefined behavior.
you do not update length, so the last element of the array is duplicated. You must pass length by reference so it is updated in the caller's scope.
Here is a corrected version:
#include <iostream>
using namespace std;
void deleteElement(int array2[], int& length, int element);
int main() {
int array1[] = { 1, 4, 3, 5, 6 };
int length = sizeof(array1) / sizeof(array1[0]); //For length of array
deleteElement(array1, &length, 4);
cout << "\nIn main function\n";
for (int i = 0; i < length; i++) {
cout << array1[i] << " ";
}
return 0;
}
void deleteElement(int array2[], int& length, int element) {
int i;
for (i = 0; i < length; i++) {
if (array2[i] == element)
break;
}
if (i == length) {
cout << "Element doesn't exist\n";
} else {
length -= 1;
for (; i < length; i++) {
array2[i] = array2[i + 1];
}
}
cout << "Testing OP in deleteElement\n";
for (i = 0; i < length; i++) {
cout << array2[i] << " ";
}
}
If you use the algorithm function std::remove, you can accomplish this in one or two lines of code without writing any loops whatsoever.
#include <algorithm>
#include <iostream>
void deleteElement(int array2[], int& length, int element)
{
int *ptr = std::remove(array2, array2 + length, element);
length = std::distance(array2, ptr);
}
int main()
{
int array1[] = { 1, 4, 3, 5, 6 };
int length = sizeof(array1) / sizeof(array1[0]); //For length of array
deleteElement(array1, length, 4);
for (int i = 0; i < length; ++i)
std::cout << array1[i];
}
Output:
1356
Note that we could have written the deleteElement function in a single line:
void deleteElement(int array2[], int& length, int element)
{
length = std::distance(array2, std::remove(array2, array2 + length, element));
}
Basically, std::remove moves the removed element to the end of the sequence, and returns a pointer to the beginning of the removed elements.
Thus to get the distance from the beginning of the array to where the removed elements are located, usage of std::distance is done to give us our new length.
To remove only the first found element, std::find can be used, and then std::copy over the elements, essentially wiping out the item:
void deleteElement(int array2[], int& length, int element)
{
int *ptr = std::find(array2, array2 + length, element);
if ( ptr != array2 + length )
{
std::copy(ptr+1,array2 + length, ptr);
--length;
}
}
int main()
{
int array1[] = { 1, 4, 3, 5, 4, 6, 9 };
int length = sizeof(array1) / sizeof(array1[0]); //For length of array
deleteElement(array1, length, 4);
for (int i = 0; i < length; ++i)
std::cout << array1[i];
}
Output:
135469
There is no need for multiple loops in deleteElement. Additionally, your removal will fail to remove all elements (e.g. 4 in your example) if your array contains more than one 4, e.g.
int array1[] = { 1, 4, 3, 4, 5 };
You can simplify your deleteElement function and handle removing multiple occurrences of element simply by keeping a count of the number of times the element is found and by using your counter as a flag to control removal, e.g.:
void deleteElement(int array2[], int& length, int element)
{
int found = 0; /* flag indicating no. element found */
for (int i = 0; i < length; i++) { /* iterate over each element */
if (array2[i] == element) { /* check if matches current */
found += 1; /* increment number found */
continue; /* get next element */
}
if (found) /* if matching element found */
array2[i-found] = array2[i]; /* overwrite elements to end */
}
length -= found; /* update length based on no. found & removed */
}
Updating your example main() to show both pre-delete and post-delete, you could do something like the following:
int main (void) {
int array1[] = { 1, 4, 3, 4, 5 };
int length = sizeof array1 / sizeof *array1; //For length of array
cout << "\nBefore Delete\n";
for (int i = 0; i < length; i++)
cout << " " << array1[i];
cout << '\n';
deleteElement(array1, length, 4);
cout << "\nAfter Delete\n";
for (int i = 0; i < length; i++)
cout << " " << array1[i];
cout << '\n';
}
Example Use/Output
Which in the case where you array contains 1, 4, 3, 4, 5 would result in:
$ ./bin/array_del_elem
Before Delete
1 4 3 4 5
After Delete
1 3 5
While you are using an array of type int (of which there are many in both legacy and current code), for new code you should make use of the containers library (e.g. array or vector, etc...) which provide built in member functions to .erase() elements without you having to reinvent the wheel.
Look things over and let me know if you have further questions.
This is because the length of the array is never updated after deleting. Logically the length should decrease by 1 if the element was deleted.
To fix this, either
Pass the length by reference and decrease it by 1 if the element is actually deleted. OR
Return from the deleteElement some value which indicates that the element was deleted. And based of that, decrease the value of length in the main function.
Recalculating the array length will not help because the element is not actually deleted in memory. So the memory allocated to he array remains same.
Other issues:
The first for loop in deleteElement should run till j < length - 1.
The for loop creates a local variable i, which shadows the i variable in outer scope, so the outer i is never updated and always remains = 0

Deleting element from an array in c++

I have read others posts, but they don't answer my problem fully.
I'm learning to delete elements from an array from the book and try to apply that code.
As far as I can grasp I'm passing array wrong or it is sending integer by address(didn't know the meaning behind that).
#include <iostream>
#include <cstdlib>
using namespace std;
void delete_element(double x[], int& n, int k);
int main()
{
// example of a function
int mass[10]={1,2,3,45,12,87,100,101,999,999};
int len = 10;
for(int i=0;i<10;i++)
{
cout<<mass[i]<<" ";
};
delete_element(mass[10],10&,4);
for(int i=0;i<10;i++)
cout<<mass[i]<<" ";
return 0;
}
void delete_element(double x[], int& n, int k)
{
if(k<1 || k>n)
{
cout<<"Wrong index of k "<<k<<endl;
exit(1); // end program
}
for(int i = k-1;i<n-1;i++)
x[i]=x[i+1];
n--;
}
There are a couple of errors in your code. I highlight some of the major issues in question 1-3:
You call exit, which does not provide proper cleanup of any objects since it's inherited from C. This isn't such a big deal in this program but it will become one.
One proper way too handle such an error is by throwing an exception cout<<"Wrong index of k "<< k <<endl;
exit(1);
Should be something like this:
throw std::runtime_error("invalid index");
and should be handled somewhere else.
You declare function parameters as taking a int& but you call the function like this: delete_element(mass[10],10&,4); 10& is passing the address of 10. Simply pass the value 10 instead.
You are "deleting" a function from a raw C array. This inherently doesn't make sense. You can't actually delete part of such an array. It is of constant compile time size created on the stack. The function itself doesn't do any deleting, try to name the functions something more task-oriented.
You are using C-Arrays. Don't do this unless you have a very good reason. Use std::array or std::vector. These containers know their own size, and vector manages it's own memory and can be re sized with minimal effort. With containers you also have access to the full scope of the STL because of their iterator support.
I suggest you rewrite the code, implementing some type of STL container
Line 15: syntax error
you can't pass a number&
If you want to pass by reference, you need to create a variable first, like:
your delete_element function signature conflicts with your declared arrays. Either use a double array or int array and make sure the signatures match.
delete_element(mass, len , 4);
when you write the name of an array without the brackets, then it's the same as &mass[0]
ie. pointer to the first element.
complete changes should be:
#include <iostream>
#include <cstdlib>
using namespace std;
void delete_element(int x[], int& n, int k);
int main(){
// example of a function
int mass[10] = { 1, 2, 3, 45, 12, 87, 100, 101, 999, 999 };
int len = 10;
for (int i = 0; i<10; i++){ cout << mass[i] << " "; };
cout << endl;
delete_element(mass, len , 4);
for (int i = 0; i<10; i++)cout << mass[i] << " ";
cout << endl;
cin.ignore();
return 0;
}
void delete_element(int x[], int& n, int k){
if (k<1 || k>n){
cout << "Wrong index of k " << k << endl;
exit(1); // end program
}
for (int i = k - 1; i<n - 1; i++)
x[i] = x[i + 1];
n--;
}
There are a couple of mistakes in your program.
Apart from some syntax issues you are trying to pass an int array to a function which wants a double array.
You cannot pass a lvalue reference of a int literal. What you want is to pass a reference to the length of the int array. see also http://en.cppreference.com/w/cpp/language/reference.
Here is an updated version of your program.
#include <iostream>
#include <cstdlib>
using namespace std;
void delete_element(int x[], int& n, int k);
int main() {
// example of a function
int mass[10] = { 1,2,3,45,12,87,100,101,999,999 };
int len = 10;
for (int i = 0;i < len;i++)
cout << mass[i] << " "; ;
cout << endl;
delete_element(mass, len, 4);
for (int i = 0;i < len;i++) // len is 9 now
cout << mass[i] << " ";
cout << endl;
return 0;
}
void delete_element(int x[], int& n, int k) {
if (k<1 || k>n) {
cout << "Wrong index of k " << k << endl;
exit(1); // end program
}
for (int i = k - 1;i<n - 1;i++)
x[i] = x[i + 1];
n--;
}
Although it does not answer your question directly, I would like to show you how you can use C++ to solve your problem in a simpler way.
#include <vector>
#include <iostream>
void delete_element(std::vector<int>& v, const unsigned i)
{
if (i < v.size())
v.erase(v.begin() + i);
else
std::cout << "Index " << i << " out of bounds" << std::endl;
}
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7};
delete_element(v, 4);
for (int i : v)
std::cout << i << std::endl;
return 0;
}
You cannot delete elements from an array, since an array's size is fixed. Given this, the implementation of delete_element can be done with just a single call to the appropriate algorithm function std::copy.
In addition, I highly suggest you make the element to delete a 0-based value, and not 1-based.
Another note: don't call exit() in the middle of a function call.
#include <algorithm>
//...
void delete_element(int x[], int& n, int k)
{
if (k < 0 || k > n-1 )
{
cout << "Wrong index of k " << k << endl;
return;
}
std::copy(x + k + 1, x + n, x + k);
n--;
}
Live Example removing first element
The std::copy call moves the elements from the source range (defined by the element after k and the last item (denoted by n)) to the destination range (the element at k). Since the destination is not within the source range, the std::copy call works correctly.

returning array from function in c++

this my program to return array from function in c++
#include <iostream>
using namespace std;
int *pTest(){
static int a[] = {2,3,4,6,9};
return a;
}
int main(){
int *x;
x = pTest();
while(*x != NULL){
cout << *x++ << " ";
}
}
according to me output should be 2 3 4 6 9
but on my machine output is 2 3 4 6 9 1,
why there is an extra 1 in the output.
i am using codeblocks ,gcc 4.8.1
Arrays aren't zero-terminated, so the loop while (*x != NULL) will keep reading beyond the array until it finds a zero-valued word, or crashes, or causes some other undefined behaviour.
You'll either need to add a terminator to the array (if you can choose a value, perhaps zero, that won't be a valid array element), or return the length in some other way.
You can use a count and take the size of the array.
Like this:
int k = 0;
while(k <= sizeof(x)){
cout << " "<< *x++;
k++;
}
With std::vector your function will be:
std::vector<int> ptest() {
static const int a[] = {2,3,4,6,9};
std::vector<int> vec (a, a + sizeof(a) / sizeof(a[0]) );
return vec;
}