2016-08-10 2 views
0

J'ai un problème avec memcpy() dans c maintenant, et j'espère que quelqu'un peut vous aider.Pourquoi mon programme plante-t-il lors du transfert de chaînes entre des pointeurs char en C?

Mon programme permet aux utilisateurs d'entrer une chaîne dans un pointeur char, puis calcule toutes les permutations possibles. Lorsque les permutations sont générées (le pointeur d'entrée de l'utilisateur est changé en une permutation), la permutation est copiée dans un second pointeur char via memcpy. Cela fonctionne parfaitement, sauf si la chaîne a deux ou plusieurs caractères répétitifs différents (par exemple "CCBB" ou "AADD"). Si l'utilisateur entre quelque chose comme ceci, memcpy (ou même strcpy) provoque le crash du programme. J'ai essayé d'allouer plus de mémoire aux deux pointeurs, mais cela s'est avéré futile. Tout le reste fonctionne sauf pour ça.

Parce que j'utilise gcc sur Windows (MinGW), les détails de mon accident ne sont pas affichés. Il dit simplement que "perm.exe a cessé de fonctionner". J'ai utilisé une série d'instructions printf() et trouvé que le programme plante sur la ligne memcpy().

Quelques détails sur le code:

Le « mot » pointeur char tient l'entrée de l'utilisateur. Il sera transformé en permutations par le programme, et son contenu sera sauvegardé dans "printPerm". "printPerm" le tableau de pointeur char qui contient les permutations, et sera plus tard utilisé pour imprimer les permutations quand elles ont été triées par ordre alphabétique et que toutes les entrées en double ont été supprimées. "permIndex" est l'index de "printPerm" et est itéré chaque fois qu'une permutation est ajoutée à "printPerm".

Désolé je n'ai pas plus de détails, mais en utilisant un éditeur de texte et gcc signifie que je n'ai pas beaucoup de débogueur. Il semble que toute méthode de transfert de données entre les pointeurs ne plantera le programme que si la chaîne contient deux ou plusieurs caractères répétitifs différents.

+1

Veuillez [modifier] votre question pour inclure un [mcve]. –

+1

"utilisateurs pour entrer une chaîne dans un pointeur char" - Mauvaise idée! Un pointeur n'est pas un tableau. Vous ne voulez absolument pas que les utilisateurs saisissent quoi que ce soit ** dans ** un pointeur! – Olaf

+1

J'ai testé votre fonction 'Permute' en écrivant ma propre fonction' main' et il semble fonctionner correctement pour les entrées que j'ai testées. J'ai testé pour 'AABB',' AABBB', etc. Je ne pense pas qu'il y ait un problème dans la fonction 'Permute' que vous avez montré ici. Pouvez-vous éditer votre question et ajouter la fonction d'où vous appelez Permute? Il y aura un problème si 'printPerm [permIndex]' ne pointe pas vers la mémoire valide, et si 'permIndex' n'est pas initialisé correctement. – sps

Répondre

0

Vous avez de la chance: ma boule de cristal vient de revenir de réparation! Voyons si cela fonctionne maintenant:

// ALL CHECKS OMMITTED! 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

static int permIndex; 

// place the two functions you published here 

// Uhmmm...well...but we need one 
int factorial(int n) 
{ 
    int f = 1; 
    do { 
    f *= n; 
    } while (--n); 

    return f; 
} 

int main(int argc, char **argv) 
{ 
    int f,i; 
    char **pperm; 
    char *word; 
    size_t length; 

    if (argc < 2) { 
    fprintf(stderr, "Usage: %s string\n", argv[0]); 
    exit(EXIT_FAILURE); 
    } 

    // work on copy 
    length = strlen(argv[1]); 
    word = malloc(length + 1); 
    strcpy(word, argv[1]); 

    // You either allocate memory as you need it but as you compute 
    // all combinations first, you need the whole memory for them 
    // at once. That means the amount of memory needed is known in 
    // advance and can be allocated at once 

    f = factorial((int) length); 
    // allocate memory for an array of (length)! pointers to char 
    pperm = malloc(f * sizeof(char *)); 
    for (i = 0; i < f; i++) { 
    // allocate memory for the n characters plus '\0' 
    pperm[i] = malloc(length + 1); 
    } 

    Permute(word, pperm, 0, length - 1); 

    // do something with the list 

    // print it 
    for (i = 0; i < f; i++) { 
    printf("%s\n", pperm[i]); 
    // we don't need the memory anymore: free it 
    free(pperm[i]); 
    } 
    // free that array of pointers mjentioned above 
    free(pperm); 
    // free the memory for the input 
    free(word); 

    exit(EXIT_SUCCESS); 
} 

Ceci est l'une des façons de le faire.