writzlpfrimpft
writzlpfrimpft

Reputation: 371

Variable argument list with ints

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

Answers (1)

cigien
cigien

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

Related Questions