Frage

In Ordnung, dies ist schon rätselhaft ich für ein bisschen.

die folgende Funktion codiert eine Zeichenfolge in der Basis 64

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

    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;
}

Nun, auf der Aufruf der Funktion Base64Enc () Ich habe:

unsigned char *B64Encoded;

Welche ist das Argument, ich auf unsigned char * dest in der Basis 64 Encoding-Funktion übergeben. Ich habe verschiedene Initialisierungen von mallocs versucht, andere Initialisierung auf NULL. Egal was ich tue, bekomme ich alle Tage eine Ausnahme, und wenn ich initialisieren es nicht dann den Compiler (VS2005 C-Compiler) wirft eine Warnung mir zu sagen, dass es nicht initialisiert wurde. Wenn ich diesen Code mit dem nicht initialisierten Variable laufen manchmal funktioniert es und einige andere nicht. Wie kann ich diesen Zeiger initialisiert und an die Funktion übergeben?

War es hilfreich?

Lösung

Sie müssen Puffer groß genug, um zuzuteilen das codierte Ergebnis enthalten. Entweder verteilen es auf dem Stapel, wie folgt aus:

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

Aber es ist leicht Stapelpufferüberlauf verursachen, indem sie zu wenig Platz Zuteilung dieser Ansatz verwendet. Es wäre viel besser, wenn man es in einem dynamischen Speicher zuweisen:

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

Vergessen Sie nicht, zu befreien (), um den zugewiesenen Puffer, nachdem Sie fertig sind.

Andere Tipps

Es sieht aus wie Sie, so etwas verwenden mögen:

// 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);

Es würde helfen, wenn Sie den Fehler zur Verfügung gestellt.

ich kann, mit Ihrer Funktion oben, um diese erfolgreich:

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

}

Sie auf jeden Fall müssen malloc Platz für die Daten. Sie müssen auch mehr Platz als src (1/4 mehr glaube ich).

malloc

A Base64-codierter String hat vier Bytes je drei Bytes in Daten-String, so srclen wenn 300 Bytes (oder Zeichen), die Länge des Base64-codierter String 400 ist.

Wikipedia eine kurze hat aber ziemlich guten Artikel über sie.

So, Aufrundung srclen zur nächsten Tupel von drei, geteilt durch drei, mal vier sollte genau genug Speicher sein.

Ich sehe ein Problem in Ihrem Code in der Tatsache, dass es das Byte nach dem Hinter null char, zum Beispiel Zugriff, wenn die String-Länge ein Zeichen ist. Das Verhalten ist dann nicht definiert und in einer geworfenen Ausnahme führen kann, wenn Puffergrenze Prüfung aktiviert ist.

Dies kann die Nachricht für den Zugriff auf nicht initialisierten Speicher im Zusammenhang erklären.

Sie sollten dann Ihren Code ändern, so dass Sie die Hinter Zeichen separat zu behandeln.

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: Hier ist eine Wikipedia-Seite beschreibt Base64-Codierung .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top