Comparator -1073741819 (0xC0000005) - c++

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])

Related

How can I solve this problem with arrays in C++?

I am working on the Edabit challenge: Get arithmetic mean of the given array. Now I have code like that:
#include <iostream>
int data;
using namespace std;
int mean(int data);
int main()
{
int data[] = { 1, 2, 3, 4 };
cout << mean(data);
}
int mean(int data)
{
double mean = 0;
for (int i = 0; i < sizeof(data) / sizeof(data[0]); i++)
{
mean += data[i];
}
mean /= sizeof(data) / sizeof(data[0]);
}
and I am stuck. I use Visual Studio 2019 on Windows 7 Professional, and I have underlined 3 characters ( data[i], and 2x data[0]). For this x Visual Studio says expression must have pointer-to-object type (Error E0142) and I have no idea what it means with this. I only know what pointer is.
In Visual studio I added the return statement, but while shortening the code here for publishing I forgot to add it. Otherwise, this wasn't the actual problem. Now I mustn't add it in the question because the comments would be wrong. The comments are related to the upper question, but my real question (for future readers stuck on this problem) is rather:
How to pass array as an argument in the function.
Now, that I am more proficient in C++, I know the terminology and how to state it, and I also know that this isn't so clear to a total beginner: you can't just write f(int[] arr) (you can't pass arrays), but you have to write f(int* arr) (you can pass a pointer that points on that array). At that time I couldn't just search it because I didn't know much of C++ terminology.
Arrays decay into pointers (an int* in this case) when passed as argument to functions. Your mean function only accepts one single int.
When the array decays into a pointer the size information is lost. You can however prevent that by defining a function that accepts arrays of the exact type and size you need. This can be done with templates:
#include <iostream>
template<typename T, size_t N>
double mean(const T (&data)[N]) {
double sum = 0;
for (size_t i = 0; i < N; ++i)
{
sum += data[i];
}
return sum / N;
}
int main()
{
int input[] = { 1, 2, 3, 4, 5, 6, 7 };
std::cout << mean(input) << '\n';
}
If you don't want to use templates (or only accept arrays of a certain size), you need to pass the size information on to the function manually:
#include <iostream>
#include <iterator> // std::size
double mean(const int* data, size_t N)
{
double sum = 0;
for (size_t i = 0; i < N; ++i)
{
sum += data[i];
}
return sum / N;
}
int main()
{
int input[] = { 1, 2, 3, 4, 5, 6, 7 };
std::cout << mean(input, std::size(input)) << '\n';
}
Your mean function, well, is mean.
1. It doesn't return a value; there is no return statement.
2. It uses variable name the same as the function (not a recommended coding style).
3. There is a global variable data that is hidden by a local variable data inside main.
4. You're confusing the compiler and the reader: the global data variable is a single int. The local variable in main is an array of int.
You should have the last line be:
return mean;

How to use `sizeof` operator inside the condition of for-loop properly? [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
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.

How does sizeof work when passing a template array? [duplicate]

This question already has answers here:
Can someone explain this template code that gives me the size of an array? [duplicate]
(4 answers)
Closed 7 years ago.
Since sizeof and templates are both compile-time. What is it about the second parameter of the template that determines the size without specifying it in the caller function?
template <typename T, size_t n> bool isInHaystack(const T (&arr)[n], const T &needle)
{ /* I know const references are best with strings and non-primitives and should
be mitigated when using ints as in the example.*/
size_t i, size = sizeof arr / sizeof T; // how does it know n is the size?
for (i = 0; i < size; ++i)
if (arr[i] == needle)
return true;
return false;
}
int main(int argc, char **argv) {
int arr[] = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21 };
cout << isInHaystack(arr, 7) << endl;
isInHaystack<int, (size_t)(sizeof(arr) / sizeof(int))>(arr, 7); // this works, too
return 0;
}
How does this size_t n get its value when passing an array? How does it know without providing it explicitly?
To make this a little more clear, this will not compile:
template <typename T> bool foo(const T(&arr)[], const T needle) {
cout << sizeof arr << endl;
return true;
}
int main(){
int arr[] = {1,2,3};
foo(arr, 1); // Error: could not deduce template argument for 'const T (&)[]' from 'int [21]'
}
What is the issue?
If you are asking "how does the compiler know to put the array size into n"... The expression
const T (&arr)[n]
is being passed
int arr[11]
hence it is able to deduce T is int and n is 11.
If you are asking how it knows how large arr is...
int arr[] = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21 };
cout << isInHaystack(arr, 7) << endl;
arr is an array. The compiler knows how big it is. If you are thinking "arr is really just a pointer", that's not true. Arrays and pointers are said to have equivalence (see K&R section 5.3), which doesn't mean they are same, but that they result in the same behavior in a limited number of contexts.
In C and C++ arrays are able to decay into pointers, but they are still not pointers until the decay occurs.
int arr[] = { 1, 3, 5, 7 };
int* arrp = arr; // decay
cout << isInHaystack(arr, 7); // Error.
See http://c-faq.com/aryptr/aryptrequiv.html

Using array in function - C [duplicate]

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.

How to pass array in C++

I trying to pass an array but don't understand why it gives me those errors. The code is also available in ideone.com
#include <iostream>
using namespace std;
class Max
{
int max = 0;
public:
int getMax(int array[], int size)
{
for(int num : array)
{
if(num > max)
max = num;
}
return max;
}
};
int main( )
{
Max m;
int arr[5] = { 5, 3, 2, 7, 6 };
cout << "Max number is: " << m.getMax(arr,5);
return 0;
}
The problem here as has been mentioned is that passing an array to a function it decays to a pointer. The fix that involves the least changes is to pass the array by reference like so:
template <int U>
int getMax(int (&array)[U])
this fix is probably not the most intuitive for a beginner though. The fix that requires a bit more changes and probably makes more sense to a beginner is to use std::vector or std::array:
int getMax(const std::vector<int> &array)
and in main:
std::vector<int> arr = { 5, 3, 2, 7, 6 };
cout << "Max number is: " << m.getMax(arr);
The cause is the for(:) can not get the size of "int array[]".
You have a size argument, but the begin() & end() can not use it. You must wrap the begin() and end() member functions or just simple it to
for(int i = 0; i< size; i++)
{
int num = array[i];
if(num > max)
max = num;
}
size argument needs type specified (proper type is size_t).
array in getMax function is a pointer (not an array). You can't use range-based for loop with it. You have to use regular for loop which will make use of size argument.