Char**, pointeur et fonction

Résolu
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009 - 16 avril 2008 à 21:03
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009 - 19 avril 2008 à 12:29
Salut,

Je bosse sur un petit programme et je butte sur un problème de pointeurs. Voici le code source qui pose problème :
--------------------
#include <stdio.h>
#include <string.h>
#include <malloc.h>

void make_arguments_table(int argc, char* argv[], char** new_argv);

int main(int argc, char* argv[])
    {
        char** arguments;
        make_arguments_table(argc, argv, arguments);
        printf("%d\n", &arguments[0]);
        return (0);
    }
   
void make_arguments_table(int argc, char* argv[], char** new_argv)
    {
        int arguments_count = argc - 2;
        int counter = 2;
        int len = 0;
        int i=0;
       
          new_argv = (char**)malloc(arguments_count * sizeof(char*));
          if (new_argv == NULL) printf("Lack of memory space.\n");
         
          for(i=0;i
--------------------
Je fais deux printf() de test. Le premier dans make_arguments_table() qui affiche l'adresse de array[0]. Le deuxième, dans main(), affiche a sont tour cette valeur qui devrait être la même... mais qui ne l'est pas.

Est ce que j'pourrais avoir un coup d'main svp ?

10 réponses

luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
16 avril 2008 à 21:20
Tu oublies que ton pointeur que tu envois en argument n'est pas modifié par la fonction.
En C++ on ferait ca:

char** arguments;
make_arguments_table(argc, argv, arguments);

void make_arguments_table(int argc, char* argv[], char** &
new_argv)

En C, faut soit passer par la valeur de retour, soit passer par un pointeur de ton pointeur, soit un (char***)
char** make_arguments_table(int argc, char* argv[])
ou
void make_arguments_table(int argc, char* argv[], char*** new_argv)
3
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
17 avril 2008 à 12:24
Bonjour,

arguments est passé par valeur à la fonction make_arguments_table, ce qui fait que les allocations mémoire qui sont faits dans la fonction le sont sur une copie locale de arguments ! Il faut passé l'adresse de arguments pour que ce pointeur soit directement utilisé et modifié (ou passer sa référence, ce qui revient au même puisque le passage par référence n'est rien d'autre qu'un passage par adresse avec une syntaxe de passage par valeur !).

PS: char** x et char* x[] c'est la même chose. Eviter d'utiliser ces 2 syntaxes en même temps, ça donne l'impression que c'est compris comme étant différents.

#include <stdio.h>
#include <string.h>
#include <malloc.h>



void make_arguments_table(int argc,char**,char***);



int main(int argc,char** argv)
{
   char** arguments;
   make_arguments_table(argc,argv,&arguments);
   printf("main:arguments    = %X\n",arguments);
   printf("main:arguments[0] = %X\n",arguments[0]);
   return 0;
}
   
void make_arguments_table(int argc,char** argv,char*** new_argv)
{
   int arguments_count = argc - 2;
   int counter = 2;
   int len = 0;
   int i=0;
       
   *new_argv = (char**)malloc(arguments_count * sizeof(char*));
   if (*new_argv == NULL)
   {
      printf("Lack of memory space (1)\n");
      return;
   }
   printf("make_arguments_table:arguments    = %X\n",*new_argv);
         
   for (i=0 ; i

Ce qui donne (programme test) :

test a b c
make_arguments_table:arguments    = 4107D0
make_arguments_table:arguments[0] = 4107C0
make_arguments_table:arguments[1] = 4107B0
main:arguments    = 4107D0
main:arguments[0] = 4107C0



Jean-François
3
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
18 avril 2008 à 17:11
Ca marche comme ça !


#include <stdio.h>
#include <string.h>
#include <time.h>
#include <malloc.h>
#include <windows.h> // Sleep()



void make_arguments_table(int argc,char** argv,char**& new_argv);
void display_help();





int main(int argc, char** argv)
{
   // No enough arguments
   if (argc < 3)
   {
      display_help();
      return (0);
   }
       
   // Wrong first argument (time hh:mm)
   if (strlen(argv[1]) != 5)
   {
      display_help();
      return (0);
   }
   if
   (
      (argv[1][0] < '0' || argv[1][0] > '2')
      ||
      (argv[1][1] < '0' || argv[1][1] > '9')
      ||
      (argv[1][2] != ':')
      ||
      (argv[1][3] < '0' || argv[1][3] > '5')
      ||
      (argv[1][4] < '0' || argv[1][4] > '9')
   )
   {
      display_help();
      return (0);
   }
       
   // Read the time
   int h=0;
   int m=0;
   time_t time_since_1970;
   struct tm* local_time;
       
   // Hour and minute from chars to integers
   h = (10 * (((int)argv[1][0]) - '0')) + (((int)argv[1][1]) - '0');
   m = (10 * (((int)argv[1][3]) - '0')) + (((int)argv[1][4]) - '0');
   if (h < 0 || h > 23 || m < 0 || m > 59)
   {
      display_help();
      return (0);
   }
       
   // Wait for the right time and execute the commands
   char** arguments;
   make_arguments_table(argc,argv,arguments);
   while (1)
   {
      time(&time_since_1970);
      local_time = localtime(&time_since_1970);
      printf("Scheduled: %02d:%02d\tLocal: %02d:%02d:%02d\n"
            ,h,m,local_time->tm_hour,local_time->tm_min,local_time->tm_sec);



      if (local_time->tm_hour h && local_time->tm_min m)
      {
         printf("time reached\n");
         int counter = 0;
         while (counter < argc - 2)
         {
            printf("execute %s\n",arguments[counter]);
            counter++;
         }
         return (0);
      }
      Sleep(5000); // wait 5 seconds before checking again
   }
   return (0);
}
   



void make_arguments_table(int argc,char** argv,char**& new_argv)
{
   int arguments_count = argc - 2;
   int counter = 2;
   int len = 0;
   int i = 0;
       
   new_argv = (char**)malloc(arguments_count * sizeof(char*));
   if (new_argv == NULL)
   {
      printf("Lack of memory space (1)\n");
      return;
   }
         
   for(i=0 ; i





void display_help()
{
   printf("usage: stask <hh:mm> <command_1> <command_2> ... <command_n>\n");
   printf("Schedule a task.\n");
   printf("  <hh:mm>\t: Specify when to execute the command.\n");
   printf("\t\t  hh = hour   (00 <= hh <= 23).\n");
   printf("\t\t  mm = minute (00 <= mm <= 59).\n");
   printf("  <command>\t: Command to execute (use quotes if it includes spaces).\n");
   printf("\t\t  You can put several commands.\n\n");
   printf("Exemple:\n$ stask 07:00 "wxvlc /home/username/playlist.m3u" "echo OK > stask.log"\n\n");
}


Ce qui donne :

stask 17:10 format "copy *.* z:\" dir
Scheduled: 17:10        Local: 17:09:21
Scheduled: 17:10        Local: 17:09:26
Scheduled: 17:10        Local: 17:09:31
Scheduled: 17:10        Local: 17:09:36
Scheduled: 17:10        Local: 17:09:41
Scheduled: 17:10        Local: 17:09:46
Scheduled: 17:10        Local: 17:09:51
Scheduled: 17:10        Local: 17:09:56
Scheduled: 17:10        Local: 17:10:01
time reached
execute format
execute copy *.* z:\
execute dir



Jean-François
3
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
19 avril 2008 à 09:48
Il faut compiler en C++, le passage par référence n'existe pas en C.

Jean-François
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
17 avril 2008 à 00:25
J'y arrive pas. Est ce que tu pourrais me donner un exemple concret stp ? (parce qu'avec seulement la déclaration de la fonction, j'ai du mal à comprendre quoi faire a l'interrieur de la fonction).

Merci pour ton aide, luhtor
0
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
18 avril 2008 à 15:46
J'ai une erreur lors du malloc sur le array[1] que je n'arrive pas à corriger. Voici le code complet, si vous pouvez me dire où ça cloche ce serait vraiment sympa.




-------------------
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <malloc.h>

void make_arguments_table(int argc, char** argv, char*** new_argv);
void display_help();

int main(int argc, char** argv)
    {
        // No enough arguments
        if (argc < 3)
            {
                display_help();
                return (0);
            }
       
        // Wrong first argument (time hh:mm)
        if (strlen(argv[1]) != 5)
            {
                display_help();
                return (0);
            }
        if ((argv[1][0] < '0' || argv[1][0] > '2')
            || (argv[1][1] < '0' || argv[1][1] > '9')
            || (argv[1][2] != ':')
            || (argv[1][3] < '0' || argv[1][3] > '5')
            || (argv[1][4] < '0' || argv[1][4] > '9'))
            {
                display_help();
                return (0);
            }
       
        // Read the time
        int h=0;
        int m=0;
        time_t time_since_1970;
        struct tm* local_time;
       
        // Hour and minute from chars to integers
        h = (10 * (((int)argv[1][0]) - '0')) + (((int)argv[1][1])-'0');
        m = (10 * (((int)argv[1][3]) - '0')) + (((int)argv[1][4])-'0');
        if (h < 0 || h > 23 || m < 0 || m > 59)
            {
                display_help();
                return (0);
            }
       
        // Wait for the right time and execute the commands
        int counter = 0;
        char** arguments;
        while (1)
            {
                time(&time_since_1970);
                  local_time = localtime(&time_since_1970);
                  if (1==1 || local_time->tm_hour == h && local_time->tm_min == m)
                      {
                          make_arguments_table(argc, argv, &arguments);
                          while (counter < (argc-2))
                              {
                                  printf("debug:arguments[%d] = %s\n", counter, argv[counter]);
                                  counter++;
                              }
                          return (0);
                      }
                  printf("Scheduled: %d:%d\tLocal: %d:%d\n", h, m, local_time->tm_hour, local_time->tm_min);
                sleep(10); // wait 10 seconds before checking again
            }
        return (0);
    }
   
void make_arguments_table(int argc, char** argv, char*** new_argv)
    {
        int arguments_count = argc - 2;
        int counter = 2;
        int len = 0;
        int i=0;
       
          *new_argv = (char**)malloc(arguments_count * sizeof(char*));
        if (*new_argv == NULL)
            {
                printf("Lack of memory space (1)\n");
                return;
            }
         
          for(i=0; i <command_1> <command_2> <command_n>\n");
        printf("Schedule a task.\n");
        printf("  <hh:mm>\t: Specify when to execute the command.\n");
        printf("\t\t  h=hour   (00 <= h <= 23).\n");
        printf("\t\t  m=minute (00 <= h <= 59).\n");
        printf("  <command>\t: Command to execute (use quotes if it include spaces).\n");
        printf("\t\t  You can put several commands.\n\n");
        printf("Exemple:\n$ stask 07:00 "wxvlc /home/username/playlist.m3u" "echo OK > stask.log"\n\n");
    }




-------------------
0
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
18 avril 2008 à 23:06
ça marche pas chez moi. gcc me renvoit deux erreurs à cause des char**&.
(j'ai enlevé le include <windows.h> parce que je suis sous linux, précision concernant le numéro des lignes...)

stask2.c:6: erreur: expected «;", «," or «)" before «&" token
stask2.c:84: erreur: expected «;", «," or «)" before «&" token
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
18 avril 2008 à 23:34
C'est compilé en C ou en C++ ?

Jean-François
0
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
19 avril 2008 à 03:11
C'est compilé en C sous ubuntu 7.10 avec gcc.
0
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
19 avril 2008 à 12:29
Yessss !! Merci beaucoup, le programme tourne :D

Cela dit, pour rester en C, j'ai renvoyé new_argv comme résultat pour m'affranchir des références.

Merci :)
0