14

This is my main.c

......
int main(int argc, char **argv)
{
    init_arg(&argc, &argv);
    ......
}

This is my init_arg.c

......
void init_arg(int *argc, char ***argv)
{
    printf("%s\n", *argv[1]);
    ......
}

I compiler it with no error and warning.

I run it:

./a.out include

It get Segmentation fault

When I debug it, I found step printf("%s\n", *argv[1]);

get wrong, It show:

print *argv[1]

Cannot access memory at address 0x300402bfd

I want to know, How to print argv[1] in init_arg() function.

3
  • 10
    +1 for debugging first and including it in your post! Commented Apr 29, 2012 at 1:16
  • In GDB when your code crashes run the command bt to see the stack trace leading up to your crash. Read crasseux.com/books/ctutorial/argc-and-argv.html for example C program code that handles program arguments. Commented Apr 29, 2012 at 1:18
  • here's a snippet with examples http://pastebin.com/SVAZjsXA Commented Apr 29, 2012 at 2:02

3 Answers 3

19

You need to add a pair of parentheses around (*argv) to change the order of evaluation. The way you currently have it, the [1] is evaluated first, yielding an invalid pointer, which then gets dereferenced, causing undefined behavior.

printf("%s\n", (*argv)[1]);
Sign up to request clarification or add additional context in comments.

7 Comments

Or, equivalently, you can use argv[0][1] (just as long to type, but perhaps slightly more readable).
@torek I would refrain from using argv[0] in place of (*argv), because what's passed in is a "scalar" pointer (i.e a pointer to a single array), rather than an array of pointers to arrays. I think that the (*argv) syntax underscores the notion that we're looking at a pointer to a scalar.
apparently you fall into the group of people who like to maintain a distinction that C drops. I sympathize! In the early 1980s, I had a colleague who liked to mix pointer and array notation all the time depending on what was convenient. In particular he'd do things like: time_t now[1]; time(now); ... instead of time_t now; time(&now); .... :-)
"[...] maintain a distinction that C drops" That's a common misconception driven primarily by arrays decaying into pointers when passed into functions. The example that you show is a good and perfectly legitimate one: there is a big difference between treating an array of one item as a pointer and treating a pointer as an array of one item.
My point is that the C language does not provide any way (in the callee, e.g., function fn) to discover whether some pointer argument T *p points to a single item (T var; fn(&var);) or to the first of N sequential items (T var[N]; fn(var);). It helps programmers to distinguish them, but the language itself does not do that for you. Compare with, e.g., Pascal and Go, which do.
|
13

Argv is already a pointer. Just pass it like this:

init_arg(&argc, argv);

And init_arg should look like this:

void init_arg(int *argc, char **argv) {
    printf("%s\n", argv[1]);
}

2 Comments

This answer is correct, but then he could also just pass argc rather than &argc. Presumably the point to passing both &argc and &argv is to allow init_arg to modify them.
You can modify them both like this.
2

I'm assuming that the reason for passing &argc and &argv in the first place is so that you can update them inside init_arg. Here's how I prefer to write such functions, in general:

/*
 * init_arg: do something useful with argc and argv, and update argc and argv
 * before returning so that the caller can do something else useful that's
 * not shared with all the other callers of init_arg().
 * (this comment of course needs updating to describe the useful things)
 */
void init_arg(int *argc0, char ***argv0) {
    int argc = *argc0;
    char **argv = *argv0;
    ... all the operative code goes here, and then ...
    *argc0 = argc;
    *argv0 = argv;
}

Of course this means you must not do early returns inside init_arg, so there are some tradeoffs, but it sure is a lot easier to work with the same regular old argc and argv inside init_arg.

1 Comment

Just use a goto if you miss the early return :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.