Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

404
Views
¿Por qué se usa strdup() aquí?

Estoy leyendo "Sistema operativo: tres piezas sencillas". En el capítulo 5, hay un fragmento de código que muestra el uso de la llamada al sistema exec().

 1 #include "common.h" 2 3 int main(int argc, char ** argv) { 4 printf("hello world (pid: %d)\n", (int) getpid()); 5 int rc = fork(); 6 if (rc < 0) { 7 fprintf(stderr, "fork failed\n"); 8 exit(1); 9 } else if (rc == 0) { 10 printf("hello, I am child (pid: %d)\n", (int) getpid()); 11 char *myargs[3]; 12 myargs[0] = strdup("wc"); 13 myargs[1] = strdup("p3.c"); 14 myargs[2] = NULL; 15 execvp(myargs[0], myargs); // run work count 16 printf("this shouldn't print out\n"); 17 } else { 18 int wc = wait(NULL); 19 printf("hello, I am parent of %d (wc: %d) (pid: %d)\n", rc, wc, (int) getpid()); 20 } 21 return 0; 22 } 23

¿Por qué se usa strdup() en la línea 12~14? He intentado reemplazar esta parte con lo siguiente:

 12 myargs[0] = "wc"; 13 myargs[1] = "p3.c"; 14 myargs[2] = NULL;

Funciona igual que el anterior.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Su versión del código está bien. Contrariamente a la respuesta de Werner, no causará un comportamiento indefinido.

Según la especificación POSIX , el prototipo de función para execvp es

 int execvp(const char *file, char *const argv[]);

Tomado en sí mismo, esto sugeriría que el contenido de las cadenas en la matriz argv podría modificarse, aunque los elementos punteros de esa matriz no podrían modificarse. Si fuera así, sería necesario pasar una matriz de punteros a cadenas de escritura, como proporcionaría strdup , y no literales de cadena, ya que escribir en un literal de cadena es un comportamiento indefinido. Esto puede haber sido lo que estaba pensando el autor del código.

Sin embargo, el texto de la especificación nos da más información:

Las matrices de punteros argv[] y envp[] y las cadenas a las que apuntan esas matrices no se modificarán mediante una llamada a una de las funciones exec, excepto como consecuencia de la sustitución de la imagen del proceso.

Entonces, de hecho, se garantiza que execvp no modificará esas cadenas. Como tal, es perfectamente seguro pasar un literal de cadena. Es posible que el autor del código original no supiera acerca de esta garantía.

La justificación más abajo explica por qué eligieron el prototipo como lo hicieron ("La declaración acerca de que argv[] y envp[] son constantes se incluye en..."). Como sugiere Werner, const char *const argv[] parecería expresar mejor el comportamiento real. Sin embargo, las reglas de conversión de punteros de C significan que si lo hubieran hecho, entonces codificarían como

 char *args[5]; args[0] = /* some writable string */; ... execvp(file, args);

no compilaría, aunque en principio está perfectamente bien. La justificación incluye una diatriba cortésmente velada sobre la semántica de const en C y cómo hacen que sea imposible escribir esto correctamente.

Hay más discusión en ¿Puedo pasar una matriz const char* a execv? .

over 4 years ago · Santiago Trujillo Report

0

El código se compila con su cambio, pero podría desencadenar un comportamiento indefinido.

execvp espera un parámetro char *const argv[] . No es la const que falta en el char . Entonces, execvp es libre de escribir en las cadenas que se le pasan.

Los literales de cadena en C no son modificables:

Los literales de cadena no se pueden modificar (y, de hecho, se pueden colocar en la memoria de solo lectura, como .rodata). Si un programa intenta modificar la matriz estática formada por un literal de cadena, el comportamiento no está definido.

Entonces, el autor del código quiere estar seguro y strdup s los literales de cadena para obtener una versión modificable de la cadena.

Tenga en cuenta que C ++ es más estricto y que gcc emitiría

advertencia: ISO C++ prohíbe convertir una constante de cadena a 'char*' [-Wwrite-strings]

por tu código.

Si execvp no modifica las cadenas de argumentos, sería mejor si tuviera una firma que expresara esto ( const char *const argv[] ).

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!