Reputation: 371
I am currently trying to understand variable argument lists in C++. I have one particular example from Java, that I'm trying to get to work:
class FindMax {
public static void main(String... args) {
System.out.println(findMax(3, 5, 7));
}
public static int findMax(int... n) {
int largest = n[0];
for (int i = 1; i < n.length; i++)
largest = (largest > n[i]) ? largest : n[i];
return largest;
}
}
Luckily for me, I found this very example on cplusplus.com. I tried running this code (which to some extent even makes sense to me):
#include <stdio.h>
#include <stdarg.h>
int FindMax (int n, ...) {
int i,val,largest;
va_list vl;
va_start(vl,n);
largest=va_arg(vl,int);
for (i=1;i<n;i++) {
val=va_arg(vl,int);
largest=(largest>val)?largest:val;
}
va_end(vl);
return largest;
}
int main () {
printf ("The largest value is: %d\n",FindMax (7, 702,422,631,834,892,104,772));
printf ("The largest value is: %d\n",FindMax (3, 5, 7));
return 0;
}
And it works.
However, notice how there is a 7 in the first call to FindMax
. I tried removing that 7 for the code to look like this:
...
int main () {
printf ("The largest value is: %d\n",FindMax (702,422,631,834,892,104,772));
printf ("The largest value is: %d\n",FindMax (3, 5, 7));
return 0;
}
And when I run this code I get either very weird numbers (e. g. 1351485333) or segfaults.
What is causing this problem?
I am using
g++ (GCC) 10.1.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
with glibc 2.31-5
.
Thanks for any help in advance.
Upvotes: 0
Views: 166
Reputation: 60238
Look at this loop:
for (i=1;i<n;i++)
The first int
that is passed to the function needs to be the number of arguments following it.
So, if you remove the 7
in the first call, the loop expects 702
ints to follow after the first argument. Since there aren't enough arguments, you are accessing invalid memory, which can cause a segfault.
Note that you don't really need the FindMax
function at all. There is already an algorithm that does this:
std::cout << std::max({4, 5, 2, 3}); // prints 5
Upvotes: 6