2010-07-06 8 views
1

J'essaie actuellement d'allouer la même quantité de mémoire pour un double pointeur. Je prends un caractère ** et je veux utiliser un tri à bulles sur ce personnage **. Donc, je crée un temp char ** et maintenant je me demande comment allouer correctement de la mémoire afin que je puisse retourner ce char temp ** à une autre méthode.allocation de mémoire double pointeur

Je sais que la façon dont j'alloue en ce moment n'a pas l'air juste et ça ne marche certainement pas ... sinon je ne poserais pas cette question. Si quelqu'un pouvait répondre avec quelques conseils utiles, je l'apprécierais grandement!

char** bubble_sort(char **filenames, int n) 
{ 
    int i; 
    char **new_list; 
    new_list = malloc(sizeof(filenames)); 
    for (i = 0; i < n; i++) 
    { 
     // malloc(file_list.size * sizeof(int)); 
     new_list[i] = filenames[i]; 
    } 
    for (i = 0; i < n; i++) 
    { 
     printf("%d: %s\n", i, new_list[i]); 
    } 

    int x; 
    int y; 
    for(x=0; x<n; x++) 
    { 
      for(y=0; y<n-1; y++) 
      { 
        if(new_list[y]>new_list[y+1]) 
        { 
          char *temp = new_list[y+1]; 
          new_list[y+1] = new_list[y]; 
          new_list[y] = temp; 
        } 
      } 
    } 
    for (i = 0; i < n; i++) 
     { 
      printf("%d: %s\n", i, new_list[i]); 
     } 
    return new_list; 
} 
+2

Ma seule recommandation est que vous utilisiez std :: vector. Se déplacer autour de char ** et jouer avec sizeof sans utiliser un seul contrôle d'assertion est une combinaison trop fréquente, qui conduit presque toujours à des bogues désagréables. Et, "malloc"? Ce n'est presque jamais nécessaire en C++, d'après mon expérience. Utilisez new [] et delete [] si vous avez vraiment besoin d'allouer des tableaux raw au lieu d'utiliser std :: vector - ce que vous devriez faire de toute façon. –

+1

et si je dois retourner un caractère **? (dans ce cas je fais ... je travaille avec un SDK et un char ** est requis) – Brandon

+1

faites toutes vos opérations avec des conteneurs STL, puis copiez le résultat dans un tableau de char correctement alloué.par exemple: "char ** pp = new char [1000] [1000];", mais pas avec malloc! –

Répondre

1

Voici la copie de travail du programme:

#include <cstdio> 
#include <cstdlib> 
#include <cstring> 

char** bubble_sort(const char **filenames, int n) 
{ 
    int i; 
    char **new_list; 
    new_list = (char**) malloc(sizeof(*new_list) * n); 
    for (i = 0; i < n; i++) 
    { 
     new_list[i] = (char*) filenames[i]; 
    } 

    printf("Initial list:\n"); 
    for (i = 0; i < n; i++) 
    { 
     printf("%d: %s\n", i, new_list[i]); 
    } 

    int x; 
    int y; 

    printf("List is sorted:\n"); 
    for(x=0; x<n; x++) 
    { 
      for(y=0; y<n-1; y++) 
      { 
        if(strcmp(new_list[y],new_list[y+1])>0) 
        { 
          char *temp = new_list[y+1]; 
          new_list[y+1] = new_list[y]; 
          new_list[y] = temp; 
        } 
      } 
    } 
    for (i = 0; i < n; i++) 
     { 
      printf("%d: %s\n", i, new_list[i]); 
     } 
    return new_list; 
} 

int main(){ 
    const char *ar[5]={ 
     "eee", "aaa", "bbb", "ccc", "ddd", 
    }; 
    bubble_sort(ar, 5); 
    return (0); 
} 

encore, gardez à l'esprit que votre style de programmation ressemble plus à C que C++ (qui est pas toujours une mauvaise chose).

Si vous souhaitez allouer de nouvelles chaînes pour vos éléments de tableau, vous devez changer la première pour comme ceci:

for (i = 0; i < n; i++) 
{ 
    //new_list[i] = (char*) filenames[i]; 
    new_list[i] = (char*) malloc(sizeof(**new_list) * (strlen(filenames[i]) + 1)); 
    strcpy(new_list[i], filenames[i]); 
} 

Et ceci est la la version C (première était la version C++). Notez que le tableau de chaînes a tous ses éléments nouvellement alloués, et n'utilise pas les chaînes initiales du paramètre d'entrée .:

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

char** bubble_sort(char **filenames, int n) 
{ 
    int i; 
    char **new_list; 
    new_list = malloc(sizeof(*new_list) * n); 
    for (i = 0; i < n; i++) 
    { 
     //new_list[i] = (char*) filenames[i]; 
     new_list[i] = malloc(sizeof(**new_list) * (strlen(filenames[i]) + 1)); 
     strcpy(new_list[i], filenames[i]); 
    } 

    printf("Initial list:\n"); 
    for (i = 0; i < n; i++) 
    { 
     printf("%d: %s\n", i, new_list[i]); 
    } 

    int x; 
    int y; 

    printf("List is sorted:\n"); 
    for(x=0; x<n; x++) 
    { 
      for(y=0; y<n-1; y++) 
      { 
        if(strcmp(new_list[y],new_list[y+1])>0) 
        { 
          char *temp = new_list[y+1]; 
          new_list[y+1] = new_list[y]; 
          new_list[y] = temp; 
        } 
      } 
    } 
    for (i = 0; i < n; i++) 
     { 
      printf("%d: %s\n", i, new_list[i]); 
     } 
    return new_list; 
} 

int main(){ 
    char *ar[5]={ 
     "eee", "aaa", "bbb", "ccc", "ddd", 
    }; 
    bubble_sort(ar, 5); 
    return (0); 
} 
+0

oups ... oui, je suis tout le programme en programmation en C++, mais j'ai oublié que c'était en C. Je vais essayer votre solution dans un instant – Brandon

+0

@Brandon Cette partie est dans C ?! Si c'est le cas, s'il vous plaît changer l'étiquette, et je vais supprimer tous mes commentaires alors qu'ils don ' Les experts C devraient parler –

+0

Notez que dans la version C, vous devez changer les fichiers d'en-tête, et il n'est pas nécessaire de lancer le cast après malloc, Oh, et encore une fois, faites attention lorsque vous comparez les cordes C. strcmp function from string.h (ou cstring si C++) –

1

filenames est un pointeur vers pointeur vers un char, donc sur cette ligne ...

new_list = malloc(sizeof(filenames)); 

... vous allouer le montant de la taille du pointeur (à pointeur), ce qui n'est pas ce que tu veux.

Vous voulez probablement malloc(sizeof(filenames) * n); qui vous donnera l'espace pour les pointeurs n.

+0

qui me donne "opérandes invalides à binaire * (ont 'char **' et 'int) – Brandon

+0

Désolé, j'ai eu une faute de frappe –

2
char** bubble_sort(char **filenames, int n) 
{ 
    int i; 
    char **new_list; 
    new_list = malloc(sizeof(filenames)); 

Ce code alloue assez d'espace pour stocker un seul pointeur (sizeof(filenames) est probablement la plupart du temps 4), et donne l'adresse de ce pointeur vers new_list. Si vous voulez accéder à ce que new_ligne désigne comme un tableau (et je sais que c'est le cas, car vous avez essayé de le faire ci-dessous), vous devrez allouer assez d'espace pour ses éléments.

0

Ceci est en quelque sorte un doublon. Voir: Creating `char ***data`?

Il y a de sérieux problèmes de performance de mémoire en ce qui concerne l'allocation de char ** pour un tableau 2D. Mieux vaut utiliser un char * et un schéma d'indexation. De cette façon, vous obtenez un morceau de mémoire contigu. Vous pouvez également utiliser un vecteur std :: un avec un tel schéma.

Si vous devez allouer un caractère **, la boucle for est tout ce que vous pouvez faire AFAIK. Mais faites au moins un sous-programme! :)