Getting the length of an array when passed to another function - c++

int *getNewArray(int arr[])
{
int newArray[15];
int len = sizeof(arr) / sizeof(arr[0]);
std::cout << len;
return newArray;
}
int main()
{
int arr[3] = {1, 2, 3};
int * newArr = getNewArray(arr);
return 0;
}
Why is the sizeof(arr) / sizeof(arr[0]) returning me 2 instead of 3? What is the right way to get the length of the passed array?

You have two problems:
Firstly, your array has automatic storage. Automatic objects are destroyed automatically at the end of scope. As such, the array no longer exists after the function returns. You return a pointer to the first element of array that does not exist after the function. The returned pointer is always invalid and therefore useless.
Secondly, there is no general way to know the size of the pointer based on a pointer to element of that array. Typically, you would pass the size of the array along with the pointer.

sizeof(arr) = 8 (on 64 bit system). Its a plain pointer
sizeof(arr[0]0 = 4 (if int is 32 bit)
hence the 2.
use std::vector or std::array

I guess the Optimized code will look something like this , maintaining the actual functionality as it is by using std::vector.
For more details I will recommend this link Vector in C++.
#include<iostream>
#include<vector>
using namespace std;
vector<int > getNewArray(vector<int >& arr)
{
int *newArray = new int[15];//creating an array of size 15 in heap
int len = arr.size();
std::cout << len;
return newArray;
}
int main()
{
vector<int > arr = {1, 2, 3};
vector<int > newArr = getNewArray(arr);
return 0;
}

Related

how do i create dynamic array in cpp

I have this function:
void reverse(int* nums, unsigned int size)
This function is supposed to reverse the values in the array it is getting.
Now for reversing I thought to create another array with the size of the array passed in. Assigning this new one from the end of the original array to the start.
But I am a kind of new in C++, So I don't know how to create dynamic array in the size of the parameter of the function.
It's actually not necessary to allocate a new array here. See if you can find a way to solve this problem just by rearranging the existing elements in-place.
Given that this seems like it's an exercise with pointers, you can allocate space by using the new[] operator:
int* auxiliaryArray = new int[size];
You'd then free it by writing
delete[] auxiliaryArray;
However, this isn't the preferred way of doing this in C++. The better route is to use std::vector, which does all its own memory management. That would look like this:
std::vector<int> auxSpace(size);
You can then access elements using the square brackets as you could in a real array. To do this, you'll need to #include <vector> at the top of your program.
In C++, the recommended way to create an array of variable size would be to use an std::vector
#include <vector>
void reverse(int* nums, unsigned int size)
{
std::vector<int> V(size);
...
}
But that approach isn't the best here for performance because it requires additional memory to be allocated of the size of the array, which could be big. It would be better to start from the outside of the array and swap members one by one that are at mirroring positions (so if the size is 5, swap 0 and 4, then swap 1 and 3 and leave 2 alone). This only requires temporary storage of a single int.
You can do it without the need to create another array:
void reverse(int* array, const int size){
for(int i = 0; i < size / 2; i++){
int tmp = array[i];
array[i] = array[size - 1 - i];
array[size - 1 - i] = tmp;
}
}
int main(){
int array[] = {1, 3, 5, 7, 9, 11};
const int size = sizeof(array) / sizeof(array[0]);
reverse(array, size);
for(int i(0); i < size; i++)
std::cout << array[i] << ", ";
}
As you can see above in the loop you only need to swap the first element (element 0) with the n-1 element and the second one with n-1-1 and son on...
Remember arrays are indexed from 0 through n-1.
If you want to allocate new array which is not practical:
int* reverse2(int* array, const int size){
int* tmp = new int[size];
for(int i(size - 1), j(0); j < size; j++, i--)
tmp[j] = array[i];
return tmp;
}
int main(){
int array[] = {1, 3, 5, 7, 9, 11};
for(int i(0); i < size; i++)
std::cout << array[i] << ", ";
std::cout << std::endl;
int* newArray = reverse2(array, size);
for(int i(0) ; i < size; i++)
std::cout << newArray[i] << ", ";
std::cout << std::endl;
delete[] newArray;
return 0;
}
If you want to use a new array you can, but I think is to kill flies with a cannon.
Looks like you are using plain C code and not C++. I say that because of the signature of the function. The signature of the function in a common C++ code could be something like this other:
void reverse(std::vector& items);
You can reverse the current array without a new array, using the current one. You are passing the pointer to the first item of the array, and the content is not constant so that you can modify it. A better signature for the function could be:
void reverse(int* const nums, const unsigned int size);
Looks like a pointer problem. Think about the boundaries to iterate the positions of the array. Would you need to iterate the whole array? Maybe only half array? ;)
As bonus track, what about to exchange the values without an auxiliar variable? (this is true into this case that we are using the fundamental type int... remember the binary arithmetic).
array[pos_head] ^= array[pos_tail];
array[pos_tail] ^= array[pos_head];
array[pos_head] ^= array[pos_tail];

Invalid Pointer?

I recently learned about pointers, and have been working hard to really understand them. However, I have run into trouble. For class we had to write a function that would double an array x amount of times. I was able to write the function without any real problems, but I'm trying to implement it into an actual code and I continue to get invalid pointer errors. Here's the code:
#include <iostream>
using namespace std;
int *ArrayDoubling(int inputArray[], int initialSize, int numberToDouble);
int main(){
int arr[2] = {0,1};
int array_size = 2;
int number = 3;
ArrayDoubling(arr, array_size, number);
}
int *ArrayDoubling(int inputArray[], int initialSize, int numberToDouble){
for(int i=0;i<numberToDouble;i++){
int *array2 = new int[initialSize*2];
for(int i=0;i<initialSize;i++){
array2[i] = inputArray[i];
array2[i+initialSize] = inputArray[i]*2;
}
initialSize = initialSize*2;
delete []inputArray;
inputArray = array2;
}
return inputArray;
}
So what exactly is causing the problem, and how can I fix it? Also not sure if this will actually print the output of the Array, but I'm also trying to get that to happen. Thanks for any and all help!
The ArrayDoubling function calls delete[] on the inputArray argument. But you pass a pointer to an automatic array when you call it in main. Calling delete[] with a pointer that you didn't get from new[] has undefined behaviour.
To fix it, only use the function with dynamically allocated arrays.
Your inner loop is looping by the number of times to double, not the size of the array. For inputs where the size of the array is less than the number of times to double, you will be accessing out of range indices.
I am not quite sure what your intension is, but I think your second for loop should look like this:
for(int i=0;i<initialSize;i++)
The biggest problem with your code is this line: delete []inputArray;
inputArray was originally declared as int arr[2] = {0,1}; which should not be deleted. You can only delete variables which were created using keyword new.
Broadly speaking, your program is going to need to look something like this. Note that new[] happens outside of the population loops in ArrayRepeat so it is only called once and similarly delete[] will only be called once, on the same pointer that was created through new[].
// dynamically allocate an array which contains the first `N` elements of
// `array` repeated `repeats` times.
int * ArrayRepeat (int * array, size_t N, int repeats) {
int * result = new int[N * repeats];
assert(result); // Error check
// Loops to populate result goes here
return result;
}
int main (void) {
int arr[] = {0, 1};
int * repeated = ArrayRepeat(arr, 2, 3);
// Print the result
for (int i = 0; i < 2 * 3; ++i) {
printf("%d\n", repeated[i]);
}
delete[] (repeated);
return 0;
}

How to get size of dynamic array in C++ [duplicate]

This question already has answers here:
How to get size c++ dynamic array
(6 answers)
Closed 9 years ago.
Code for dynamic array by entering size and storing it into "n" variable, but I want to get the array length from a template method and not using "n".
int* a = NULL; // Pointer to int, initialize to nothing.
int n; // Size needed for array
cin >> n; // Read in the size
a = new int[n]; // Allocate n ints and save ptr in a.
for (int i=0; i<n; i++) {
a[i] = 0; // Initialize all elements to zero.
}
. . . // Use a as a normal array
delete [] a; // When done, free memory pointed to by a.
a = NULL; // Clear a to prevent using invalid memory reference.
This code is similar, but using a dynamic array:
#include <cstddef>
#include <iostream>
template< typename T, std::size_t N > inline
std::size_t size( T(&)[N] ) { return N ; }
int main()
{
int a[] = { 0, 1, 2, 3, 4, 5, 6 };
const void* b[] = { a, a+1, a+2, a+3 };
std::cout << size(a) << '\t' << size(b) << '\n' ;
}
You can't. The size of an array allocated with new[] is not stored in any way in which it can be accessed. Note that the return type of new [] is not an array - it is a pointer (pointing to the array's first element). So if you need to know a dynamic array's length, you have to store it separately.
Of course, the proper way of doing this is avoiding new[] and using a std::vector instead, which stores the length for you and is exception-safe to boot.
Here is what your code would look like using std::vector instead of new[]:
size_t n; // Size needed for array - size_t is the proper type for that
cin >> n; // Read in the size
std::vector<int> a(n, 0); // Create vector of n elements initialised to 0
. . . // Use a as a normal array
// Its size can be obtained by a.size()
// If you need access to the underlying array (for C APIs, for example), use a.data()
// Note: no need to deallocate anything manually here

c++ initial value of dynamic array

I need to dynamically create an array of integer. I've found that when using a static array the syntax
int a [5]={0};
initializes correctly the value of all elements to 0.
Is there a way to do something similar when creating a dynamic array like
int* a = new int[size];
without having to loop over all elements of the a array? or maybe assigning the value with a for loop is still the optimal way to go?
Thanks
Sure, just use () for value-initialization:
int* ptr = new int[size]();
(taken from this answer to my earlier closely related question)
I'd do:
int* a = new int[size];
memset(a, 0, size*sizeof(int));
I'd advise you to use std::vector<int> or std::array<int,5>
Value initialize the elements with ()
Example:
int *p = new int[10]; // block of ten uninitialized ints
int *p2 = new int[10](); // block of ten ints value initialized to 0
To initialize with other values than 0,
for pointer array:
int size = 10;
int initVal = 47;
int *ptrArr = new int[size];
std::fill_n(ptrArr, size, initVal);
std::cout << *(ptrArr + 4) << std::endl;
std::cout << ptrArr[4] << std::endl;
For non pointer array
int size = 10;
int initVal = 47;
int arr[size];
std::fill_n(arr, size, initVal);
Works pretty Much for any DataType!
!Be careful, some compilers might not complain accessing a value out of the range of the array which might return a non-zero value
int *a=new int[n];
memset(a, 0, n*sizeof(int));
That sets the all the bytes of the array to 0. For char * too, you could use memset.
See http://www.cplusplus.com/reference/clibrary/cstring/memset/ for a more formal definition and usage.

reverse c++ array

my aim is to reverse an array 3,12,2,1 to 1,2,12,3. when i run this code i get garbage before my actually result. i can't seem to see where the problem is please assit
#include<iostream>
using namespace std;
int rev (int arr[], int a){
//int r;
for(int i =a-1; i>=0; i--){
cout<<arr[i]<<" ";
}
return 0;
}
int main(){
int arr[] = {6,41,12,5,2};
cout<<"The rev of {6,41,12,5,2}"<<endl;
cout<<rev(arr, sizeof(arr))<<endl;
system("pause");
return 0;
}
Use sizeof(arr)/sizeof(arr[0]) instead of sizeof(arr).
sizeof(arr) gives the total size of the array. sizeof(arr[0]) is the size of one array element (all elements have the same size). So sizeof(arr)/sizeof(arr[0]) is the number of elements.
An optimized answer to the question would be using reverse () from STL if you are allowed to use it:
std::reverse
http://www.sgi.com/tech/stl/reverse.html
int main()
{
int arr[] = {6,41,12,5,2};
cout<<"The rev of {6,41,12,5,2}"<<endl;
reverse(arr, arr + 5);
copy(arr, arr + 5, ostream_iterator<int>(cout, ", "));
}
sizeof return the size in bytes. In your example, if sizeof(int) = 4, it returns 20.
Because you're using an array, you have to keep the size of the array handy as well. sizeof computes the size of a value in memory, in this case the size of all the memory used to represent arr. You can do sizeof(arr)/sizeof(int) to get the number of elements in an array. This makes sense because it's taking the total size of the array and dividing it by the size of an element in the array. Beware however that this only works for arrays (int arr[4] = {6,41,12,5,2};). If it's a pointer to a heap-allocated array via something like int* i = new int[4]; you'll need to keep the size of the array hanging around.
Also, you're calling your reverse function from within a cout<< call, which will print the function's return value (in this case it's hard-coded to 0).
It also turns out there is a function in the C++ standard library (std::reverse) that can do this.
If I may speak subjectively and in an off-topic manner about your approach, it is very un-C-like. My personal favorite way to reverse an array goes like this:
void reverse(int *a, int n)
{
int *p = a, *q = a + n - 1;
while (p < q)
{
int swap = *p;
*p++ = *q;
*q-- = swap;
}
}
// Usage:
int a [] = { /* ... */ };
reverse(a, sizeof(a)/sizeof(*a));
Of course, since your question is tagged c++, there's always std::reverse().
Sizeof operator return the one extra (arrayLength + 1) here 6 will return when passs 6 it store in a when a-1 you get 5 but array index start from 0 length-1 that from 0 to 4 here i pointing to index 5 that is not last element last+1 that why you got garbage value