Function returning array with rubbish values [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 14 days ago.
Improve this question
I am trying to allocate an array on the heap so that I can return it as the output of a function that is supposed to reverse the order of the elements. when I run the program, however, The first element of array1 is missing and I get rubbish at the start of array2. Am I declaring the array wrong?
Also, since I am working with dynamic memory, must I release the memory with the delete command or will it be deleted automatically as it is within the local scope of the reverseArray function?
#include <iostream>
unsigned *reverseArray(unsigned *arr)
{
unsigned *output = (unsigned*) malloc(sizeof(int)*5);
for(unsigned i = 0; i < 5; ++i)
output[i] = arr[5 - i];
return output;
}
int main()
{
unsigned array1[5] = {10, 20, 30, 40, 50};
unsigned *array2 = reverseArray(array1);
for(unsigned i = 0; i < 5; ++i)
std::cout << array2[i] << " ";
std::cout << std::endl;
return 0;
}
The output I get is
32751 50 40 30 20

As pointed out in the comments, your index was wrong: 5-i accesses fields 5,4,3,2,1. Leaving out 0 and much more importantly, accessing past the end of the array.
However, you can just use the standard library's std::reverse function template, which even operates in-place:
#include <algorithm>
#include <iterator>
#include <iostream>
int main()
{
unsigned array1[5] = {10, 20, 30, 40, 50};
std::reverse(std::begin(array1), std::end(array1));
for(auto const& value: array1)
std::cout << value << ' ';
std::cout << '\n';
}
In case you want to keep the original array, use std::array, which has a handy copy constructor:
#include <algorithm>
#include <array>
#include <iostream>
int main()
{
std::array<unsigned,5> const array1{10, 20, 30, 40, 50};
auto array2 = array1;
std::reverse(std::begin(array2), std::end(array2));
for(auto const& value: array1) std::cout << value << ' ';
std::cout << '\n';
for(auto const& value: array2) std::cout << value << ' ';
std::cout << '\n';
}
This has the advantage that no dynamic allocations are performed. std::reverse also operates entirely in-place, so there is nothing to clean up afterwards.
If you have an array of values that is not known at compile time, like your array1 is, you can use std::vector which takes care of mopping up memory after you're done with it. std::reverse works with that as well.

The problem is in this line:
output[i] = arr[5 - i];
Since i will get the values [0,1,2,3,4], 5 - i will get the values [5,4,3,2,1].
In order to get 0 based indices ([4,3,2,1,0]) as required, you need to subtract 1:
output[i] = arr[4 - i]; // 5 - i - 1
A side note:
It's better to use std::vector for dynamic arrays in C++.
Among other advantages, it will save you the need (and potential bugs) of manual new and delete (or malloc and free although they are altogether discouraged in c++ in favor of new/delete in the rare case they are needed).

If you are writing a C++ program then use the operator new instead of the C function malloc.
For example
unsigned *output = new unsigned[5];
And you always should free all the allocated memory when it is not required any more.
Your function has undefined behavior because in this statement
output[i] = arr[5 - i];
when i is equal to 0 there is an access to memory outside the passed array because in this case the statement is look like
output[0] = arr[5];
Also the function parameter should have the qualifier const because passed arrays are not changed within the function.
Also using the magic number 5 within the function makes the function useless.
The program can look the following way
#include <iostream>
#include <iterator>
unsigned * reverseArray( const unsigned *arr, size_t n )
{
unsigned *output = nullptr;
if ( n != 0 )
{
output = new unsigned[n];
for ( std::size_t i = 0; i < n; ++i )
{
output[i] = arr[n - i - 1];
}
}
return output;
}
int main()
{
unsigned array1[] = { 10, 20, 30, 40, 50 };
const std::size_t N = std::size( array1 );
unsigned *array2 = reverseArray( array1, N );
for ( std::size_t i = 0; i < N; i++ )
{
std::cout << array2[i] << ' ';
}
std::cout << std::endl;
delete [] array2;
return 0;
}
Pay attention to that there is standard algorithm std::reverse_copy that can be used. Using this algorithm the program can look the following way
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
unsigned array1[] = { 10, 20, 30, 40, 50 };
const std::size_t N = std::size( array1 );
unsigned array2[N];
std::reverse_copy( std::begin( array1 ), std::end( array1 ),
std::begin( array2 ) );
for ( const auto &item : array2 )
{
std::cout << item << ' ';
}
std::cout << std::endl;
return 0;
}
There is no need to allocate dynamically a new array. Otherwise you could write for example
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
unsigned array1[] = { 10, 20, 30, 40, 50 };
const std::size_t N = std::size( array1 );
unsigned *array2 new unsigned[N];
std::reverse_copy( std::begin( array1 ), std::end( array1 ),
array2 );
for ( std::size_t i = 0; i < N; i++ )
{
std::cout << array2[i] << ' ';
}
std::cout << std::endl;
delete [] array2;
return 0;
}
If you need to reverse the source array then use another algorithm std::reverse the following way
std::reverse( std::begin( array1 ), std::end( array1 ) );

Related

Why doesn't push_back keep working in a loop?

Completely new to C++. Programmed selection sort on 1D array of arbitrary length. Want to allow user to keep inputting integers into console to make an array of desired length, to be subsequently sorted.
Can only seem to make arrays of length 2 using a while loop for adding elements. Code and example of erroneous result when inputting 6, 2, 3, and 9 shown below.
Script:
// Preprocessor directives and namespace declaration
#include <iostream>
#include <vector>
using namespace std;
// Function
void SelectionSort(int *arr, int len)
{
// Loop through index j in arr
for (int j = 0; j < len; j++) {
// Assume element j is minimum, and initialise minIndex
int min = arr[j];
int minIndex = j;
// Loop through comparisons to determine actual minimum
// (of elements after and including j)
for (int i = j; i < len; i++)
{
if (min > arr[i])
{
min = arr[i];
minIndex = i;
}
}
// Swap minimum with element j
int temp = arr[j];
arr[j] = min;
arr[minIndex] = temp;
}
// Display resulting array
for (int i = 0; i + 1 < len; i++)
{
cout << arr[i] << ", ";
}
cout << arr[len - 1] << endl;
}
// Main
int main()
{
// Explain program to user
cout << "Sort 1D array of user-inputted length/contents" << endl;
cout << "To finish array, enter -999" << endl;
// Initialise dynamic array
vector<int> vDyn (1);
vDyn[0] = 0;
cout << "Enter first element of array: ";
int firstElement = 0;
cin >> firstElement;
vDyn[0] = firstElement;
// Loop to define elements until desired length reached
bool keepGoing = true;
while (keepGoing == true)
{
cout << "Enter another element: ";
int newElement = 0;
cin >> newElement;
if (newElement != -999)
{
vDyn.push_back(newElement);
} else
{
keepGoing = false;
}
}
// Convert vector to array (dynamic to static)
int* v = &vDyn[0];
// Get array length
int len = sizeof(v) / sizeof(v[0]);
// Run SelectionSort function
SelectionSort(v, len);
return 0;
}
Terminal:
Sort 1D array of user-inputted length/contents
To finish array, enter -999
Enter first element of array: 6
Enter another element: 2
Enter another element: 3
Enter another element: 9
Enter another element: -999
2, 6
This declaration
int len = sizeof(v) / sizeof(v[0]);
is equivalent to the declaration
int len = sizeof( int * ) / sizeof( int );
because the variable v is declared like
int* v = &vDyn[0];
The size of a pointer is equal usually to 4 or 8 bytes. So the variable length will have the value either 1 or 2 and does not depend on the number of elements stored in the vector..
Instead you should use for example
size_t len = vDyn.size();
You could declare the function like
void SelectionSort(int *arr, size_t len);
and call it like
SelectionSort( vDyn.data(), vDyn.size() );
Also as in C++ there is standard function std::swap declared in the header <utility> then instead of this code snippet
// Swap minimum with element j
int temp = arr[j];
arr[j] = min;
arr[minIndex] = temp;
you could just write
if ( j != minIndex ) std::swap( arr[j], arr[minIndex] );
And the inner for loop could look like
for ( size_t i = j + 1; i < len; i++)
^^^^^
In fact your function SelectionSort is a C function. A C++ function should be more general and use iterators. In this case it could sort arrays along with other containers.
Here is a demonstration program that shows a more general function called for an array based on a vector.
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
template <typename ForwardIterator>
void SelectionSort( ForwardIterator first, ForwardIterator last )
{
for ( ; first != last; ++first )
{
auto current_min = first;
for ( auto next = std::next( first ); next != last; ++next )
{
if ( *next < *current_min ) current_min = next;
}
if ( current_min != first )
{
std::iter_swap( current_min, first );
}
}
}
int main()
{
std::vector<int> v = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << '\n';
SelectionSort( v.data(), v.data() + v.size() );
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
In general you need also to write an overloaded function that accepts also a comparison function.
// Convert vector to array (dynamic to static)
int* v = &vDyn[0];
This line doesn't convert the array to anything. You merely take address of the first element in the vector.
If you want to take an underlying c-array from std::vector you are supposed to use data property of it.
Also, since the array is decayed into a pointer, it no longer contains data of its size. You should rely on std::vector properties (i.e. std::vector::size) to pass this information forward

Why am I not able to find the length of those array in cpp [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am trying to find the length of this array and am wanting to find its length so I can use it in a for loop.
// importing needed libraries
#include <iostream>
#include <string>
#include <cmath>
#include <set>
// preventing need of std::cout, std::endl etc
using namespace std;
int main()
{
int nums[] = {1, 2, 3, 4, 5, 6};
int size;
size = nums.size();
cout << size;
for (int i = 0; i < size; i++)
{
cout << nums[i] << endl;
}
return 0;
}
The line using the .size() method is the one which is causing issues
The issue:-
error: member reference base type 'int [6]' is not a structure or union
From what I understand, my use of the .size() should be correct, but its clear not.
Arrays do not have methods. So this code snippet is incorrect.
int size;
size = nums.size();
If your compiler supports C++ 17 then you can include the header
#include <iterator>
and then write
size_t size = std::size( nums );
Or you could even write yourself such a function like for example
template <size_t N>
size_t array_size( const int ( &a )[N] )
{
return N;
}
and in main write
size_t size = array_size( nums );
Another approach is to include the header
#include <type_traits>
and write
size_t size = std::extent<decltype( nums )>::value;
Or you can just write
size_t size = sizeof( nums ) / sizeof( *nums );
Pay attention to that to output the array you need not to know its size. You could write
for ( const auto &item : nums )
{
cout << item << endl;
}
The array also can be outputted using iterators like
#include <iterator>
//...
for ( auto first = std::begin( nums ); first != std::end( nums ); ++first )
{
cout << *first << endl;
}
Using iterators you can also get the number of elements in the array like
auto size = std::distance( std::begin( nums ), std::end( nums ) );
Also I want to offer another way:
#include <iostream>
using namespace std;
void solve()
{
int numbers[] = {1, 2, 3, 4, 5, 6};
int numbersSize=0;
for(int& item : numbers)
{
cout<<item<<", ";
++numbersSize;
}
cout<<endl<<"numbersSize <- "<<numbersSize<<endl;
return;
}
int main()
{
solve();
return 0;
}
Here is the result:
1, 2, 3, 4, 5, 6,
numbersSize <- 6
So, the sense of the parameter numbersSize is the size of the parameter numbers.

How do i initialize an array in a fucntion whose length is given by a formal parameter in C++

for example,
int func(int len){
int arr[len];
}
this doesn't compile. with the error
expression did not evaluate to a constant.
so, how can i initialize an array in such a way?
In fact the function deals with a variable length array. The C++ Standard does not allow to use variable length arrays though some compilers have their own language extensions that support variable length arrays.
So in any case you have to allocate the array dynamically/. Either you can do this using the operator new as it is shown in the demonstrative program below
#include <iostream>
#include <memory>
#include <numeric>
void func( size_t n )
{
std::unique_ptr<int[]>a( new ( std::nothrow ) int[n] );
if ( a )
{
std::iota( a.get(), a.get() + n, 0 );
for ( size_t i = 0; i < n; i++ ) std::cout << a[i] << ' ';
std::cout << '\n';
}
}
int main()
{
func( 10 );
return 0;
}
The program output is
0 1 2 3 4 5 6 7 8 9
Or you can use the standard container std::vector that itself allocates dynamically memory.
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
void func( size_t n )
{
std::vector<int> v( n );
std::iota( std::begin( v ), std::end( v ), 0 );
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
}
int main()
{
func( 10 );
return 0;
}
The program output is the same as shown above.
Because your variable given could be dynamic I would use a vector:
#include <vector>
int func(const int len){
std::vector<int> arr(len);
}
if you want to avoid std::vector, you would use const (not required, but in the control structure you would not change the value):
int func(const int len){
int arr[len];
}
It least my compiler g++ 9.2 accepts that, but only if the feature Variable Length Array (VLA) is enabled. That is not part of the C++ standard though.
Static arrays like arr[] must have known length at compile time. You need to dynamically allocate, so use:
Int* arr = new int[len];
Basically, u need to allocate the array dynamically, therefore u can use new or malloc, in this case,
int fun(int len)
{
int *ar;
ar=new int [len];
for(int i=0;i<len;i++)
{
cin>>ar[i];
}
}
Now its all upto you what you want from your code now .
remmber if u are using malloc include header file in c or c++

Why am I getting zero in the output?

So I'm trying to swap two numbers without using a third variable. I pass the two numbers I'm trying to swap by reference. When the same number is to be swapped (like 1 is to be swapped with 1), I get an output of zero. I know how to fix this, but I'm unable to understand as to why I keep getting 0 when a and b are the same.
Can anyone explain why I'm getting zero instead of the swapped numbers?
void swap(int *a,int *b)
{
//if(a==b)
// return;
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
int main()
{
int n=3,x=0,y=0;
int a[n][n];
for(int i=0;i<n;i++)
swap(&a[x][i],&a[i][y]);
return 0;
}
It seems you are trying to swap elements of the first row with elements of the first column.
For starters variable length arrays is not a standard C++ feature. Though some compilers have their own language extensions you should avoid their using.
Also the swap function can have undefined behavior because when there is an overflow of a signed integer then the result is undefined. It is better to use the standard C++ function std::swap.
And in your program you are using an uninitialized array.
Here is a demonstrative program that shows how you could write the code
#include <iostream>
#include <utility>
int main()
{
const size_t N = 3;
int a[N][N];
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
a[i][j] = i * N + j;
}
}
for ( const auto &row : a )
{
for ( const auto &item : row )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
for ( size_t i = 0; i < N; i++ )
{
std::swap( a[0][i], a[i][0] );
}
for ( const auto &row : a )
{
for ( const auto &item : row )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
return 0;
}
Its output is
0 1 2
3 4 5
6 7 8
0 3 6
1 4 5
2 7 8
If you want to write your own swap function then write it like
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
and use it in the program like
::swap( &a[0][i], &a[i][0] );
As far as i understood your code. You are trying to swap first row elements with its corresponding elements in the first column..
You are getting 0 at position a[0][0] in the matrix.
The reason is simple..
Look at this steps in your code
*b=*a-*b;
*a=*a-*b;
You are substracting same from that value..
Obviously result will be 0.
And yeh the idea of swapping row with column is really creative 👍👍👍

While loop iterating on too many elements in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
When I run the code I get all those numbers as outputs which means that my while loop seems to be going over elements that it should not got over. Why is this happening ?
For context I am currently learning C++ with a tour of C++ and I am very confused with pointer and references.
This is where I got the code:
Buggy code in "A Tour of C++" or non-compliant compiler?
int counter(int* arr,int c){
int counter = 0;
while(*arr){
cout << *arr<<"\n";
if(*arr == c){
++counter;
}
++arr;
}
return counter;
}
int main()
{
int arr[3] = {1,2,3};
int count = counter(arr,1);
cout<< count;
}
Example run:
/Users/benediktschesch/CLionProjects/untitled/cmake-build-debug/untitled
1
2
3
-945684358
-1153026697
-280532248
32766
1839025881
32767
1839025881
32767
1
Process finished with exit code 0
This is very similar to not providing a null terminator for a character array that will be used as a string.
while(*arr)
means stop when you find a zero.
int arr[3] = {1,2,3};
provides no zero, therefore you have no control over when the loop will stop.
TL;DR Solution:
Use a Library container. std::vector or std::array would be a good fit here, as would std::count from the <algorithm> library and std::begin and std::end from the <iterator> library.
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
int arr[] = { 1, 2, 3 };
int count = std::count(std::begin(arr), std::end(arr), 1);
std:: cout << count;
}
Explanation:
You could provide a zero
int arr[] = {1,2,3,0};
Note I remove the explicit array size. It's not needed because the compiler knows from the number of elements in the initialzer.
Note also that this will stop upon reaching the first zero, so
int arr[] = {1,2,3,0,1,2,3,0};
will only spot one 1. This makes zero a very poor value to use to terminate a list of integers unless 0 is guaranteed to not be in the input.
To scan the whole array and only the array, the size of the array needs to be provided. This can be done by passing in a size parameter
int counter(int* arr, size_t len, int c)
{
int counter = 0;
while (len--)
{
std::cout << *arr << "\n";
if (*arr == c)
{
++counter;
}
++arr;
}
return counter;
}
int main()
{
int arr[3] = { 1, 2, 3 };
int count = counter(arr, std::size(arr), 1);
std:: cout << count;
}
but the preferred solution in Modern C++ would be to use a container in place of the array. Containers know their size and offer up a wide variety of other tools to make writing code easier and less error-prone.
#include <iostream>
#include <vector>
int counter(const std::vector<int> & arr, int c)
{
int counter = 0;
for (const auto & val: arr)
{
std::cout << val << "\n";
if (val == c)
{
++counter;
}
}
return counter;
}
int main()
{
std::vector<int> arr = { 1, 2, 3 };
int count = counter(arr, 1);
std:: cout << count;
}
Note the use of a range-based for loop to simplify the code. const auto & val deduces the type of val from the contents of arr with auto. The value is not going to be changed as a result of the loop so we declare it const to prevent accidents and make it a reference because maybe the compiler can pull off some extra optimization voodoo. In addition you can keep reusing this exact statement without having to change a thing if the container or the type of data in the container is ever changed. This prevents mistakes later when maintaining the code.
You could also use std::array and make counter a templated function that detects the size of the std::array here, but that's a bit much at this point.
The next evolution takes advantage of the <algorithm> library.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> arr = { 1, 2, 3 };
int count = std::count(arr.begin(), arr.end(), 1);
std:: cout << count;
}
In this case Iterators are being used rather than specifying lengths. This lets you easily scan subsets of a container.
This allows us to go back to using a vanilla array by taking advantage of std::begin and std::end to turn the array into a pair of iterators :
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
int arr[] = { 1, 2, 3 };
int count = std::count(std::begin(arr), std::end(arr), 1);
std:: cout << count;
}
And that brings us around to the TL;DR solution.
I recommend to use std::array and range based for loops
#include <array>
#include <iostream>
int counter(const std::array<int, 3> &arr, int c){
int counter = 0;
for (auto const a : arr) {
std::cout << a << "\n";
if(a == c){
++counter;
}
}
return counter;
}
int main()
{
std::array<int, 3> arr = {1,2,3};
int count = counter(arr,1);
std::cout << count;
}
The reason for your problem is that in the line
while(*arr){
the statement
*arr
is evaluated as boolean. It is false for *arr == 0 and true in any other case. In your code you need to get the size of the array or a last element with value 0. There are different ways. You can add a last element with 0 or you can pass the size to the function. But C++ standard provides stl containers that solve your problem without overhead. std::array is such a container that contains the data and the size of your array. It is a template class so that there is no extra data needed for the size. First you should learn how to use the tools that a language provides like stl containers and algorithms. Later you can learn how to use low level functions and data types.
Except character arrays that contain strings all other arrays (if you do not use intentionally a sentinel value) do not contain a zero element that signals the end of an array. So your function can invoke undefined behavior if the array does not contain an element equal to 0 (as in your case).
So in general your function should have one more parameter that specifies the number of elements in the array and should look like
size_t counter( const int *arr, size_t n, int value )
{
size_t count = 0;
for ( const int *p = arr; p != arr + n; ++p )
{
if ( *p == value ) ++count;
}
return count;
}
and called like
int main()
{
int arr[] = { 1, 2, 3 };
const size_t N = sizeof( arr ) / sizeof( *arr );
size_t count = counter( arr, N, 1 );
std::cout << count << '\n';
}
If your compiler supports C++ 17 then instead of the expression sizeof( arr ) / sizeof( *arr ) you can include standard function std::size() declared in the header <iterator> like std::size( arr ).
Otherwise instead of the expression sizeof( arr ) / sizeof( *arr ) you could use expression
std::extent<decltype( arr )>::value
provided that the header <type_traits> is included.
Take into account that there is standard algorithm std::count declared in header <algorithm> that performs the same task. Here is a demonstrative program
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
int arr[] = { 1, 2, 3 };
auto count = std::count( std::begin( arr ), std::end( arr ), 1 );
std::cout << count << '\n';
}