How is this array is altering its value? [duplicate] - c++

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;
}

Related

Resolving Dynamic Memory Allocation problem in array function [duplicate]

This question already has answers here:
How to return local array in C++?
(12 answers)
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 months ago.
I am learning to apply C++ pointers by creating a program that can multiply the combination of numbers from two arrays and pass the list of numbers in a newly created array. But the result produced from the program outputs garbage values in the result, probably a dangling pointer problem.
Here's my code:
#include <iostream>
using namespace std;
void print(int *array[], size_t array_size);
int *apply_all(int array1[], size_t size1, size_t array2[], int size2);
void print(int array[], size_t array_size) {
cout << "[ ";
for (size_t i{0}; i < array_size; ++i)
cout << array[i] << " ";
cout << "]" << endl;
}
int *apply_all(int array1[], size_t size1, int array2[], int size2) {
int new_array [size1 * size2] {};
int *array_ptr {new_array};
for (size_t i_1{0}; i_1 < size1; ++i_1) {
for (size_t i_2{0}; i_2 < size2; ++i_2) {
*array_ptr = array1[i_1]*array2[i_2];
array_ptr++;
}
}
return array_ptr;
}
int main() {
const size_t array1_size {5};
const size_t array2_size {3};
int array1 [] {1,2,3,4,5};
int array2 [] {10,20,30};
cout << "Array 1: ";
print(array1, array1_size);
cout << "Array 2: ";
print(array2, array2_size);
int *results = apply_all(array1, array1_size, array2, array2_size);
constexpr size_t results_size {array1_size * array2_size};
cout << "Result: ";
print(results, results_size);
}
Output:
Array 1: [ 1 2 3 4 5 ]
Array 2: [ 10 20 30 ]
Result: [ 0 1249712272 500 -353954405 32759 14 0 3 0 5 0 562035404 117 58 0 ]
Do I have to do something with dynamic memory allocation?

Why is my permutation code generating duplicates?

My code is generating duplicates (3) to be precise and I don't know why, could anyone help out?
I've tried searching for a problem, but to my eyes it seems the same as other premutation codes on the internet.
I was thinking it could've been a miss-use of the loop but I don't see why it's giving me 9 answers instead of 6.
#include <iostream>
using namespace std;
void swap(char *a, int x, int y);
void print(char *a, int n);
void permute(char *a, int n, int index);
int grabSize(char a[]);
int main() {
char array[] = {'a', 'b', 'c'}; // PLACE COMPONENTS HERE
int n = grabSize(array);
//
cout << "[" << endl;
cout << " ";
permute(array, n, 0);
cout << endl << "]";
}
int grabSize(char a[]) {
int i = 0;
while (a[i] != '\0') {
i++;
}
return i;
}
void swap(char *a, int x, int y) {
char aux;
aux = a[x];
a[x] = a[y];
a[y] = aux;
}
void permute(char *a, int n, int index) {
if (index == n-1) {
print(a, n);
return;
}
for (int i = 0; i < n; i++) {
swap(a, i, index);
permute(a, n, index+1);
swap(a, i, index);
}
}
void print(char *a, int n) {
cout << " [ ";
for (int i = 0; i < n; i++) {
cout << a[i];
}
cout << " ] ";
}
You are getting 9 combinations of string because, in permute(), the for loop variable i initialised with 0:
for (int i = 0; i < n; i++) {
^^^
Note that you are calling permute() function recursively to generate the permutations of string and, in every recursive call, the index is incremented by 1 while passing to permute() function but the for loop , in permute() function, starts with 0 and iterate till < n. Hence you are getting n*n combinations of string in output. Instead, the for loop variable i should be initialised with index:
for (int i = index; i < n; i++) {
^^^^^
Other problems in your code:
This
char array[] = {'a', 'b', 'c'};
is array of 3 characters. Note that there is no terminating null character in array array. Passing it to grabSize() function and checking for '\0' character in it will lead to UB as grabSize() function will end up accessing array array beyond its size while looking for null terminating character. To get the size of array, you can simply do sizeof(array)/sizeof(array[0]) in main() function and do away with grabSize() function.
If you are inclined to use grabSize() function then either add null terminating character manually
char array[] = {'a', 'b', 'c', '\0'};
or initialise array array with string, like this
char array[] = "abc";
and then pass it to grabSize() function.
Suggestion:
In C++, the use of plain C style array is discouraged. C++ has Containers Library, go through it. The sequence container array and vector will be of your interest.

The numbers in my bubble sort array output incorrectly after being sorted [duplicate]

This question already has an answer here:
Array not playing back properly inside function - bubble sort
(1 answer)
Closed 2 years ago.
I am learning bubble sort. In my output array, the numbers in my presort array output correctly, but the second time it outputs with the sorted numbers it omits the 0 in the 10. I get an output of: Before sort: Array = {10, 2, 3, 1} After sort: Array = {1, 2, 3, 1} Any ideas?
#include <iostream>
using namespace std;
void showArray(int sortMe[], int size);
int main()
{
int sortMe[4] = {10, 2, 3, 1}; // Original Array
int numElements = 4;
int temp; // For swapping
cout << "Before sort: ";
showArray(sortMe, numElements);
for (int i=numElements-1; i>0; i--) { // For loop1
for(int j=0; j<i; j++) {
// Checks if the value on left is bigger than the right
if(sortMe[j] > sortMe[j+1]) {
// If bigger swap values
temp = sortMe[j];
sortMe[j] = sortMe[j+1];
sortMe[j+1] = temp;
}
}
}
cout << "After sort: ";
showArray(sortMe, numElements);
}
void showArray(int sortMe[], int size) {
// Outputs array in format array = {num1, num2, etc.}
int i = 0;
cout << "Array = {";
for (int i = 0; i < size - 1; i++) {
cout << sortMe[i] << ", ";
}
cout << sortMe[i] << "}" << endl;
}
Your problem is not the sorting, but printing. You define i two times.
If you rewrite your for loop inside the print like this your problem is solved for (; i < size - 1; i++).
The way you've written it the last element is always the element at index 0 because of int i = 0; outside of the loop.

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

Pass subarray to function

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