web-dev-qa-db-fra.com

Assigner de la mémoire à un double pointeur?

J'ai du mal à comprendre comment affecter de la mémoire à un double pointeur. Je veux lire un tableau de chaînes et le stocker.

    char **ptr;
    fp = fopen("file.txt","r");
    ptr = (char**)malloc(sizeof(char*)*50);
    for(int i=0; i<20; i++)
    {
       ptr[i] = (char*)malloc(sizeof(char)*50);
       fgets(ptr[i],50,fp);
    }

au lieu de cela, je viens d'attribuer un grand bloc de mémoire et stocker la chaîne

  char **ptr;
  ptr = (char**)malloc(sizeof(char)*50*50);

cela serait-il faux? Et si oui pourquoi?

12
lazy_hack

Votre deuxième exemple est faux car, théoriquement, chaque emplacement de mémoire ne contiendrait pas un char* mais plutôt une char. Si vous modifiez légèrement votre façon de penser, cela peut vous aider:

char *x;  // Memory locations pointed to by x contain 'char'
char **y; // Memory locations pointed to by y contain 'char*'

x = (char*)malloc(sizeof(char) * 100);   // 100 'char'
y = (char**)malloc(sizeof(char*) * 100); // 100 'char*'

// below is incorrect:
y = (char**)malloc(sizeof(char) * 50 * 50);
// 2500 'char' not 50 'char*' pointing to 50 'char'

À cause de cela, votre première boucle serait comment vous faites en C un tableau de tableaux de caractères/pointeurs. L'utilisation d'un bloc de mémoire fixe pour un tableau de tableaux de caractères est acceptable, mais vous utiliseriez un seul char* plutôt qu'un char**, car vous ne disposeriez d'aucun pointeur dans la mémoire, mais simplement de chars.

char *x = calloc(50 * 50, sizeof(char));

for (ii = 0; ii < 50; ++ii) {
    // Note that each string is just an OFFSET into the memory block
    // You must be sensitive to this when using these 'strings'
    char *str = &x[ii * 50];
}
12
user7116

je vais donner un exemple, ce qui pourrait effacer le doute,

char **str;                              // here its kind a equivalent to char *argv[]
str = (char **)malloc(sizeof(char *)*2)  // here 2 indicates 2 (char*)
str[0]=(char *)malloc(sizeof(char)*10)   // here 10 indicates 10 (char)
str[1]=(char *)malloc(sizeof(char)*10)   // <same as above>

strcpy(str[0],"abcdefghij");   // 10 length character 
strcpy(str[1],"xyzlmnopqr");   // 10 length character

cout<<str[0]<<endl;    // to print the string in case of c++
cout<<str[1]<<endl;    // to print the string in case of c++

or

printf("%s",str[0]);
printf("%s",str[1]);  

//finally most important thing, dont't forget to free the allocated mem
free(str[0]);
free(str[1]);
free(str);
2
Abhishek D K

Un double pointeur est juste un pointeur sur un autre pointeur. Donc, vous pouvez l'affecter comme ceci:

char *realptr=(char*)malloc(1234);
char **ptr=&realptr;

Vous devez garder à l'esprit l'emplacement de stockage de votre pointeur (dans cet exemple, le pointeur double pointe sur une variable de pointeur de la pile et est donc invalide après le retour de la fonction).

1
Pent Ploompuu

autre moyen plus simple de mémoriser

Cas 1 :

étape 1: char * p;

étape -2: s'il vous plaît lire comme ci-dessous

carbonisé (* p); ==> p est un pointeur sur un caractère

maintenant, il vous suffit de faire malloc pour le type (étape 2) sans accolades

c'est-à-dire, p = malloc (sizeof (char) * some_len);

Cas -2:

étape 1: char ** p;

étape 2 :

veuillez le lire comme ci-dessous

char * (* p); ==> p est un pointeur sur un caractère *

maintenant, il vous suffit de faire malloc pour le type (étape 2) sans accolades

c'est-à-dire p = malloc (sizeof (char *) * some_len);

Cas -3:

Personne ne l'utilise mais juste pour des raisons d'explication

char *** p;

lisez-le comme

caractère ** (* p); ==> p est un pointeur sur un caractère ** (et pour cette vérification cas 2 ci-dessus)

p = malloc (sizeof (char **) * some_len);

1
ravi chandra
 char **ptr;
    fp = fopen("file.txt","r");
    ptr = (char**)malloc(sizeof(char*)*50);
    for(int i=0; i<50; i++)
    {
       ptr[i] = (char*)malloc(sizeof(char)*50);
       fgets(ptr[i],50,fp);
    }

fclose(fp);

peut-être votre faute de frappe mais votre boucle devrait être de 50 au lieu de 20 si vous recherchez une matrice 50 x 50. De même, après l’allocation de mémoire mentionnée ci-dessus, vous pouvez accéder au tampon sous la forme ptr [i] [j], c’est-à-dire au format 2D. 

1
AnkitSahu

En ajoutant à la réponse de Pent, comme il l’a bien fait remarquer, vous ne pourrez plus utiliser ce double pointeur une fois la fonction retournée, car elle pointera sur un emplacement mémoire de la fiche d’activation de la fonction qui est désormais obsolète revenu). Si vous souhaitez utiliser ce double pointeur après le retour de la fonction, vous pouvez procéder comme suit:

char * realptr = (char *) malloc(1234);
char ** ptr = (char **) malloc(sizeof(char *));
*ptr = realptr;
return ptr;

Le type de retour de la fonction doit évidemment être char ** pour cela.

0
Rohan Saxena