This question already has answers here:
Why does a C-Array have a wrong sizeof() value when it's passed to a function? [duplicate]
(6 answers)
Closed 9 years ago.
#include <stdio.h>
#include <iostream>
using namespace std;
int write(int arr[])
{
int n = (sizeof(arr)/sizeof(arr[0]));
for(int r=0;r<n;r++)
{
printf("%d\n", arr[r]);
}
return 0;
}
int main()
{
int numlist[] = {1, 3, 5, 6, 7, 9, 0, 2, 3};
write(numlist);
std::string strvar;
std::cin >> strvar;
}
What is being printed on the screen is just the number '1'. Nothing more.
Just beginning C and I'm only trying to get the hang of the syntax.
You cannot compute the size of the array inside the function using
(sizeof(arr)/sizeof(arr[0]));
That is because the function only sees arr as a pointer (the array decayed into a pointer), not as a full array. Thus, n will be 1.
You have to pass the size as an extra argument.
int write(int arr[], int n)
{
for(int r=0;r<n;r++)
printf("%d\n", arr[r]);
return 0;
}
and call it with
write(numlist, sizeof(arr)/sizeof(arr[0]));
Inside
int write(int arr[])
arr is a int*. sizeof(arr)/sizeof(arr[0]) comes out as 1 for you because pointers have the same size as integers on your system.
You can only calculate the number of elements in an array when you have access to its definition. In your case, this is inside main only. If you want to pass the array to another function you also need to pass its length
int write(int* arr, size_t num_elems)
{
for(int r=0;r<num_elems;r++) {
printf("%d\n", arr[r]);
}
return 0;
}
int main()
{
int numlist[] = {1, 3, 5, 6, 7, 9, 0, 2, 3};
size_t num_elems = sizeof(arr)/sizeof(arr[0]);
write(numlist, num_elems);
}
Alternatively, if you define a sentinel value that marks the end of the array, you don't need to pass a length
int write(int* arr)
{
while (*arr != -1) {
printf("%d\n", *arr);
arr++;
}
return 0;
}
int main()
{
int numlist[] = {1, 3, 5, 6, 7, 9, 0, 2, 3, -1}; /* element with value -1
marks the end of the
array */
write(numlist);
}
The problem is the following line
int n = (sizeof(arr)/sizeof(arr[0]));
In this context C has no idea what the length of arr is. Arrays in C just don't have an inherent length property. Hence when you say sizeof(arr) it translates into 1 not the number of elements.
In order to make this work you need to explicitly pass the number of elements in the array to the function along with the array
int n = (sizeof(arr)/sizeof(arr[0])); does not work in this context, since arr is a function parameter which has decayed to a pointer at this point. Either pass the number of elements to the function or use a sentinel value to mark the end of the array.
in C/C++, when arrayname passed as parameter, it's convert to an pointer.
so in that function sizeof(arr) is and equal to sizeof(int*).
int C++
int a[10];
int (&b)[10] = a; // b is a reference of int array whose length is 10;
//so here could be ok
template< size_t n>
size_t write(int (& new_array_name)[n])
{
//
}
On 64 bit Operating System, sizeof(arr[0]) is returning 4 bytes while sizeof(arr) is returning 2 bytes. On my system, n has value 2. Due to this reason, loop is executing r<2 times on my system. On 32 bit Operating system, sizeof(arr[0]) returns 2 bytes instead of 4 bytes. That's why you are getting index 0 of arr to be executed only.
Related
I'm implementing Binary search. But I don't want to pass the size of an array as an argument in the binarySearch function. I'm trying to find array size in function. I use sizeof operator, but the output of the binary search is wrong. when I try to pass the size of array as an argument then the output is fine. My question is why & what is the problem for calculating array size in function? is it possible to calculate array size in function?
Here is my approach:
code
#include <bits/stdc++.h>
using namespace std;
void binarySearch(int arr[], int value)
{
int c = sizeof(arr) / sizeof(arr[0]);
//cout << c;
int low = 0, high = c - 1, notFound = 1;
while (low <= high)
{
int mid = (low + high) / 2;
if (arr[mid] == value)
{
cout << "Found at index " << mid << endl;
notFound = 0;
break;
}
if (arr[mid] < value)
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
if (notFound == 1)
{
cout << "Not Found" << endl;
}
}
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 9, 56, 88};
int x = 3;
binarySearch(arr, x);
//cout << p << endl;
}
output:
tempCodeRunnerFile.cpp:5:22: warning: 'sizeof' on array function parameter 'arr' will return size of 'int*' [-Wsizeof-array-argument]
int c = sizeof(arr) / sizeof(arr[0]);
^
tempCodeRunnerFile.cpp:3:23: note: declared here
void binarySearch(int arr[], int value)
~~~~^~~~~
Not Found
My expected Output:
Found at index 2
My question is why & what is the problem for calculating array size in function
The problem is that arr is a pointer to an element of the array. The size of the pointer has nothing to do with the size of the array, which is why your attempted sizeof(arr) cannot work.
The warning message also explains this quite well.
is it possible to calculate array size in function?
Given only a pointer to an element, it is generally1 not possible to determine the size of the array. That is why you must pass the size as an argument.
Another approach which I prefer is to encapsulate the pointer and the length in a class. There is a standard class template for this purpose: std::span.
void binarySearch(std::span<int> arr, int value)
{
int c = arr.size();
...
// call as in your example:
int arr[] = {1, 2, 3, 4, 5, 6, 9, 56, 88};
int x = 3;
binarySearch(arr, x);
1 There are techniques that allow this, but they have draw backs.
One technique is to choose one element value as a "terminator" aka "sentinel" which signifies the end of the array. That way, you can do a linear search for the terminator to determine the length. This is commonly used in C with strings, where the null terminator character terminates the string. This technique isn't an option if you cannot dedicate any of the values as a terminator. The other obvious drawback is the linear complexity of the size calculation which is asymptotically more expensive than the binary search that you're implementing
There is a further possibility that you could use, but calling it with too many different array sized might cause code bloat.
template<std::size_t N>
void binarySearch(int arr[N], int value)
And then use N instead of c.
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
Do the conditions of the for-loop always need constant?
How can I put sizeof function there to run an output showing all the elements of an array?
#include<iostream>
using namespace std;
void array_output(int a[])
{
for (int i = 0; i < (sizeof(a)) / (sizeof(a[0])); i++)
{
cout << a[i] << endl;
}
}
int main()
{
int a[] = { 22, 53, 13, 65, 80, 31, 46 };
array_output(a);
return 0;
}
i<(sizeof(a) output shows first 4 elements
i<(sizeof(a))/(sizeof(a[0])) output shows only the first element
instead of sizeof when 7 is directly used as a condition, it gives
the right output, showing all the elements.
†(This answer is for c++17 users...)
where no need of using sizeof operator at all.
Use instead std::size() function which will get you the size of the given container or array.
#include <iostream>
#include <iterator> // std::size
#include <cstddef> // std::size_t
int main()
{
int a[]{ 22,53,13,65,80,31,46 };
for (std::size_t i = 0; i < std::size(a); i++)
{
std::cout << a[i] << `\n`;
}
}
† Update
The OP has edited the question after posting this answer,
where the std::size can not be applied.
When the array a passed to void array_output(int a[]), it deduced to void array_output(int* a)
instead if of the its actual type int a[7].
i<(sizeof(a) output shows first 4 elements
Here, you are doing size of(int*) (pointer to int), depending up
on the architecture
it could be efferent. In your case it is 32 bit machine which is why you got sizeof(a) = 4.
i < sizeof(a)/ sizeof(a[0]) output shows only the first element
Dividing sizeof(a)(which is sizeof(int*) equal to 4 bytes in
your machine) by sizeof(a[0])(which is sizeof(int), also 4 bytes), is nothing but one and loops only once.
The #Timo's
answer, provide a templated function where size will be a non-type template parameter, which can be accessed directly, without going for sizeof.
How can I put sizeof in function and run an output showing all the
elements of an array?
This is possible only when passing the array a of actual type as it is.
For that, let the array to deduce to its int [7], by forwarding it perfectly.
#include<iostream>
template<typename Type>
void array_output(Type&& a) // deduced to `int a[7]`
{
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { // or std::size(a)
std::cout << a[i] << '\n';
}
}
int main()
{
int a[] = { 22, 53, 13, 65, 80, 31, 46 };
array_output(a);
return 0;
}
If you use the actual array in the sizeof operator you will get the size of the array in bytes, meaning you can calculate the number of elements like you expected it using sizeof(array) / sizeof(array_type).
int x[] = {1, 1, 1, 1, 1, 1};
int sum = 0;
for (int i = 0; i < sizeof(x) / sizeof(int); i++)
sum += x[i];
// sum == 6
However if you pass the array as a function parameter you will encounter pointer decay. This means that the array size information is lost and you get the pointer size instead, which is the behavior that you described.
int sum(int arr[]) // arr decays to int*
{
int sum = 0;
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
sum += arr[i];
return sum;
}
int main()
{
int x[] = {1, 1, 1, 1, 1, 1};
return sum(x); // will return 1 or 2, depending on architecture
}
You can still get the array size in the function if you use a template function for it.
#include <cstddef>
template <std::size_t N>
int sum(int (&arr)[N])
{
int sum = 0;
for (int i = 0; i < N; i++)
sum += arr[i];
return sum;
}
int main()
{
int x[] = {1, 1, 1, 1, 1, 1};
return sum(x); // will return 6
}
You can use vector for this.
vector<int> nums{1,2,3,4};
for(std::size_t i = 0; i < nums.size(); ++i)
cout<<nums[i]<<endl;
If you insist on using int a[], you should be aware of the size before traversing it.
By the way, on GCC
sizeof(nums) = sizeof(int) * total number of element
it's not the total number of element.
This is the code to find a number in the array and return its index. But what if I have the same 2 numbers and I want to return both their indexs ?
int find_pos (int a[], int index, int n)
{
if ( a[index] == n)
{
return index;
}
else
{
return find_pos (a, index + 1, n);
}
}
int main()
{
int a[] = {3, 1, 5, 6, 0, 6, 8, 4};
cout << find_pos (a, 0, 6);
}
You could use a vector<int> to hold the indices of found values. That is, instead of returning when you find a matching value, just save the index into your vector and continue searching. This means that your recursion base case has to change. You'll have to search all the way to the end of the array. Since you're using a C-style array, you'll have to also pass in the length of the array too, so that recursive function calls can know when to stop.
I am trying to compare numbers from an array using this other method. I am not sure how it's called but it's this:
template<typename T>
using Comparator = bool(*)(T, T);
My code gets build, but when i started it, it crashes on this line:
if(comp(arr[i], arr[i+1])){
with error message: -1073741819 (0xC0000005)
what am I doing wrong and what is the name of this method for comparing values ?
#include <iostream>
using namespace std;
template<typename T>
using Comparator = bool(*)(T, T);
template<typename T>
void theHell(T arr[], int len, Comparator<T> comp){
for(int i = 0; i < len - 1; i++){
if(comp(arr[i], arr[i+1])){
cout << "pice of code" << endl;
}
}
}
int main()
{
int arr[] = { 1, 3 ,3 ,4, 4, 67, 5, 32, 4};
Comparator<int> comp;
int len = sizeof(arr);
theHell(arr, len, comp);
return 0;
}
Comparator<int> is a function pointer type that takes 2 ints and returns a bool.
That means that comp is a pointer to a function. What function? You haven't told it what function to use. You need to point it at a function like so:
bool compare_func(int a, int b) { return a < b; }
...
int main() {
Comparator<int> comp = compare_func;
what am I doing wrong
comp is an uninitialized function pointer, it's obvious that you get a crash when calling it inside the template.
Also, you are passing the array length in bytes (as returned by sizeof), while your function expects a number of elements.
and what is the name of this method for comparing values ?
"access violation", I guess.
To fix your code, you have to write a comparison function compatible with the function signature of your function pointer, and use it to initialize comp; also, fix the initialization of n by dividing it by sizeof(int).
Incidentally, generic functions usually accept a more general parameter for comparison functions, so to allow the library user to pass any callable (be it a function, a functor, a lambda, an std::function, ...) to the template.
You have two problems:
First:
int len = sizeof(arr);
This line will give you teh size of the array * the size of the int in you platform. You just need the size of your array. So, you should divide it by the size of int:
int len = sizeof(arr)/sizeof(int);
Second:
Your comeratror has no defnetion. However, it may be better if you use std::function like this:
#include <iostream>
#include <functional>
template<typename T>
void theHell(T arr[], int len, std::function<bool(int,int)> comp){
for(int i = 0; i < len - 1; i++){
if(comp(arr[i], arr[i+1])){
cout << "pice of code" << endl;
}
}
}
int main()
{
int arr[] = { 1, 3 ,3 ,4, 4, 67, 5, 32, 4};
auto comp=[](auto a,auto b){return a<b;};
int len = sizeof(arr)/sizeof(int);
theHell(arr, len, comp);
return 0;
}
sizeof gives you the array size in bytes. theHell() is called with a len of 36 (9 ints á 4 byte) instead of 9 so you get a memory access violation error when accessing arr[10] in theHell().
To get the number of elements you have to use sizeof(arr) / sizeof(arr[0])
This question already has answers here:
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 8 years ago.
#include <iostream>
using namespace std;
int function(int arr [])
{
int y = sizeof(arr)/sizeof(arr[0]);
return y;
}
int main ()
{
int arr[] = {1,2,3,4,5,6};
int x = sizeof(arr)/sizeof(arr[0]);
cout <<x<<"\n";
int y=function(arr);
cout <<y<<"\n";
return 0;
}
int arr[] = {1,2,3,4,5,6};
int x = sizeof(arr)/sizeof(arr[0]);
In this case arr is an array of 6 int elements. sizeof of an int is 4 bytes, thus sizeof(arr) is 24, divided by sizeof of a single int equals 6.
int function(int arr [])
{
int y = sizeof(arr)/sizeof(arr[0]);
return y;
}
In this case arr decays to a pointer to an int. Depending on your platform, sizeof of a pointer might be 4 or 8 bytes.
The output will be as follows:
6
1
Explanation:
When you compute x inside the main() function, arr is an array. Therefore, sizeof(arr) returns the size of the whole array in bytes.
int x = sizeof(arr) / sizeof(arr[0]);
// 24 / 4 = 6 (assuming your compiler assigns 4 bytes to an integer)
But when you pass the same to a function, what gets passed as the parameter is the pointer to the array. So, this is essentially like passing int *arr to the function.
Source: C++ Size of Array