2012-04-29 18 views
14

Ésta es mi main.cun puntero sobre * argv []

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

Esta es mi init_arg.c

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

I compilador sin ningún error y advertencia.

lo ejecuto:

./a.out include

Se consigue culpa Segmentación

Cuando depurarlo, encontré paso printf("%s\n", *argv[1]);

equivocarse, que se muestran:

print *argv[1]

Cannot access memory at address 0x300402bfd

Quiero saber, Cómo imprimir argv[1] en init_arg() función.

+10

+1 para eliminar errores primero e incluirlo en su publicación! – jedwards

+0

En GDB cuando el código falla, ejecute el comando bt para ver el seguimiento de la pila que conduce a su bloqueo. Lea http://crasseux.com/books/ctutorial/argc-and-argv.html, por ejemplo, código de programa C que maneja los argumentos del programa. –

+0

aquí hay un fragmento con ejemplos [http://pastebin.com/SVAZjsXA](http://pastebin.com/SVAZjsXA) – dschulz

Respuesta

19

Debe agregar un par de paréntesis alrededor (* argv) para cambiar el orden de evaluación. En la forma en que actualmente lo tiene, el [1] se evalúa primero, generando un puntero no válido, que luego se desreferencia, lo que causa un comportamiento indefinido.

printf("%s\n", (*argv)[1]); 
+1

O, de forma equivalente, puede usar 'argv [0] [1]' (tan largo como tipo, pero tal vez un poco más legible). – torek

+7

@torek Me abstendría de usar 'argv [0]' en lugar de '(* argv)', porque lo que se pasa es un puntero "escalar" (es decir, un puntero a una sola matriz), en lugar de una matriz de punteros a las matrices. Creo que la sintaxis '(* argv)' subraya la noción de que estamos viendo un puntero a un escalar. – dasblinkenlight

+0

aparentemente caes en el grupo de personas a las que les gusta mantener una distinción que C caiga. ¡Yo simpatizo!A principios de la década de 1980, tuve un colega al que le gustaba mezclar puntero y notación todo el tiempo, dependiendo de lo que fuera conveniente. En particular, haría cosas como: 'time_t now [1]; Ahora); ... 'en lugar de' time_t ahora; time (&now); ... '. :-) – torek

13

Argv ya es un puntero. Sólo tiene que pasar de esta manera:

init_arg(&argc, argv); 

Y init_arg debería tener este aspecto:

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

Esta respuesta es correcta, pero también podría pasar 'argc' en lugar de' & argc'. Presumiblemente, el punto de pasar tanto '& argc' como' & argv' es permitir que 'init_arg' los modifique. – torek

+0

Puede modificarlos de esta manera. – alf

2

estoy suponiendo que la razón para pasar &argc y &argv en el primer lugar es para que pueda actualizarlos dentro de init_arg. Así es como yo prefiero escribir tales funciones, en 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; 
} 

Por supuesto, esto significa que no se debe hacer temprano return s dentro init_arg, así que hay algunas ventajas y desventajas, pero seguro que es mucho más fácil trabajar con el el mismo viejo normal argc y argv dentro de init_arg.

+1

Solo usa un goto si pierdes el regreso temprano :) – hugomg

Cuestiones relacionadas