Ukazatel initializiation? pro specifickou funkci

hlasů
1

Dobře, tohle se mě zaráží na chvíli.

následující funkce kóduje řetězec do základu 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;
}

Nyní, na volání funkcí Base64Enc () mám:

unsigned char *B64Encoded;

Což je argument projdu na unsigned char * dest ve funkci kódování základny 64. Zkoušel jsem různé inicializace z mallocs NULL na jiné inicializace. Bez ohledu na to, co dělám, jsem vždycky dostat výjimku, a pokud nemám ho inicializovat pak kompilátor (VS2005 C kompilátor) hází varování mi říct, že to nebyla inicializována. Mám-li spustit tento kód s un-inicializuje proměnnou někdy to funguje a nějaký jiný není. Jak mohu inicializovat tento ukazatel a předat jej do funkce?

Položena 24/06/2009 v 22:18
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
1

Vidím problém v kódu v tom, že mohou získat přístup k bajt po odtokové null char, například v případě, že délka řetězce je jeden znak. Chování je pak definován a může mít za následek házet výjimku, pokud je aktivována kontrola pufr hranice.

To může vysvětlit zpráva týkající se přístupu k neinicializované paměti.

pak byste měli změnit svůj kód tak, aby zvládnout koncové znaky samostatně.

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: Zde je stránka wikipedia popisující kódování Base64 .

Odpovězeno 25/06/2009 v 11:24
zdroj uživatelem

hlasů
1

Base64 kódovaný řetězec má čtyři bajty na tři byty v-datovém řetězci, takže pokud srclen je 300 bajtů (nebo znaky), délku pro base64 řetězce je 400.

Wikipedia má krátký, ale velmi dobrý článek o tom.

Takže, zaokrouhlování srclen k nejbližšímu tice ze tří, děleno třemi, krát čtyři by mělo stačit přesně paměti.

Odpovězeno 24/06/2009 v 22:35
zdroj uživatelem

hlasů
1

To by pomohlo, pokud za předpokladu, že došlo k chybě.

Mohu s vaší funkcí výše, s tím úspěšně:

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

}

Budete určitě potřebovat malloc prostoru pro data. Také je potřeba malloc větší prostor než src (1/4 víc věřím).

Odpovězeno 24/06/2009 v 22:31
zdroj uživatelem

hlasů
1

Vypadá to, že budete chtít použít něco jako toto:

// 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);
Odpovězeno 24/06/2009 v 22:27
zdroj uživatelem

hlasů
1

je třeba přidělit vyrovnávací paměť dostatečně velký, aby obsahoval kódovaný výsledek. Buď přidělit ji na zásobník, jako je tento:

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

Ale to je snadné způsobit přetečení zásobníku vyrovnávací paměti přidělování příliš málo místa použití tohoto přístupu. Bylo by mnohem lepší, kdyby jej rozdělit do dynamické paměti:

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

Nezapomeňte uvolnit () přidělené vyrovnávací paměti poté, co jste udělal.

Odpovězeno 24/06/2009 v 22:27
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more