2009-06-24 5 views
1

D'accord, celui-ci m'a un peu énervé un peu.Initialisation de pointeur? pour une fonction spécifique

la fonction suivante encode une chaîne dans la base 64

void Base64Enc(const unsigned char *src, int srclen, unsigned char *dest) 
{ 
    static const unsigned char enc[] = 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 

    unsigned char *cp; 
    int i; 

    cp = dest; 
    for(i = 0; i < srclen; i += 3) 
    { 
     *(cp++) = enc[((src[i + 0] >> 2))]; 
     *(cp++) = enc[((src[i + 0] << 4) & 0x30) 
        | ((src[i + 1] >> 4) & 0x0f)]; 
     *(cp++) = enc[((src[i + 1] << 2) & 0x3c) 
        | ((src[i + 2] >> 6) & 0x03)]; 
     *(cp++) = enc[((src[i + 2] ) & 0x3f)]; 
    } 
    *cp = '\0'; 
    while (i-- > srclen) 
     *(--cp) = '='; 

    return; 
} 

Maintenant, la fonction d'appel Base64Enc() Je:

unsigned char *B64Encoded; 

Quel est l'argument que je passe sur unsigned char * dest dans la fonction de codage de base 64. J'ai essayé différentes initialisations de mallocs à NULL à d'autres initialisations. Quoi que je fasse, je reçois toujours une exception et si je ne l'initialise pas, alors le compilateur (compilateur C VS2005) lance un avertissement m'indiquant qu'il n'a pas été initialisé. Si j'exécute ce code avec la variable non-initialisée, parfois ça marche et pas d'autre. Comment initialiser ce pointeur et le passer à la fonction?

Répondre

1

Vous devez allouer suffisamment de mémoire tampon pour contenir le résultat codé. Soit allouer sur la pile, comme ceci:

unsigned char B64Encoded[256]; // the number here needs to be big enough to hold all possible variations of the argument 

Mais il est facile de faire déborder le tampon de la pile en allouant trop peu d'espace en utilisant cette approche. Il serait beaucoup mieux si vous allouez dans la mémoire dynamique:

int cbEncodedSize = srclen * 4/3 + 1; // cbEncodedSize is calculated from the length of the source string 
unsigned char *B64Encoded = (unsigned char*)malloc(cbEncodedSize); 

Ne pas oublier de libérer() le tampon alloué après que vous avez terminé.

+0

Votre premier exemple (unsigned char * B64Encoded [256];) est faux - il doit être: (unsigned char B64Encoded [256]) - Vous créez un tableau de 256 char ptrs, pas 256 chars. – DaveR

+0

oui, merci! corrigé – Rom

1

Il semble que vous voulez utiliser quelque chose comme ceci:

// allocate 4/3 bytes per source character, plus one for the null terminator 
unsigned char *B64Encoded = malloc(srclen*4/3+1); 

Base64Enc(src, srclen, B64Encoded); 
+0

(srclen + 1) ne suffit pas pour le codage en base64. L'exemple ci-dessus provoquera un dépassement de tampon dans la fonction Base64Enc() – Rom

+0

Ouais ma mauvaise désolé –

1

Il serait utile si vous avez fourni l'erreur.

je peux, avec votre fonction ci-dessus, à ce succès:

int main() { 
    unsigned char *B64Encoded; 
    B64Encoded = (unsigned char *) malloc (1000); 
    unsigned char *src = "ABC"; 
    Base64Enc(src, 3, B64Encoded); 

} 

Vous certainement besoin d'espace malloc pour les données. Vous avez également besoin de malloc plus d'espace que src (1/4 plus je crois).

1

Chaîne codée base64 a quatre octets par trois octets dans les données chaîne, de sorte que si srclen est de 300 octets (ou des caractères), la longueur de la base64 chaîne codée est 400.

Wikipedia a une brève mais assez bon article à ce sujet. Donc, en arrondissant à l'unité la plus proche de trois, divisée par trois, quatre fois devrait être exactement assez de mémoire.

1

Je vois un problème dans votre code dans le fait qu'il peut accéder à l'octet après le caractère nul final, par exemple si la longueur de la chaîne est un caractère. Le comportement est alors indéfini et peut entraîner une exception levée si la vérification des limites du tampon est activée.

Cela peut expliquer le message relatif à l'accès à la mémoire non initialisée.

Vous devez ensuite modifier votre code afin de gérer les caractères de fin séparément.

int len = (scrlen/3)*3; 
for(int i = 0; i < len; i += 3) 
{ 
    // your current code here, it is ok with this loop condition. 
} 

// Handle 0 bits padding if required 
if(len != srclen) 
{ 
    // add new code here 
} 

... 

PS: Voici une page wikipedia décrivant Base64 encoding.

Questions connexes