2009-06-24 3 views
1

Хорошо, это меня немного озадачило.Указатель инициализации? для определенной функции

следующая функция кодирует строку в базу 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; 
} 

Теперь на вызывающую функцию Base64Enc() У меня есть:

unsigned char *B64Encoded; 

Какой аргумент я прохожу на неподписанные символ * Dest в функции кодирования базы 64. Я пробовал различные инициализации от mallocs до NULL до другой инициализации. Независимо от того, что я делаю, я всегда получаю исключение, и если я его не инициализирую, то компилятор (компилятор VS2005 C) выдает предупреждение о том, что он не был инициализирован. Если я запускаю этот код с неинициализированной переменной, иногда он работает, а другой - нет. Как инициализировать этот указатель и передать его функции?

ответ

1

вам нужно выделить буфер, достаточно большой, чтобы содержать закодированный результат. Либо передать его в стеке, например:

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

Но это легко вызвать переполнение стека буфера путем выделения слишком мало места, используя этот подход. Было бы гораздо лучше, если бы вы передать его в динамической памяти:

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

Не забудьте освободить() выделенный буфер после того как вы сделали.

+0

Ваш первый пример (unsigned char * B64Encoded [256];) неверен - он должен быть: (unsigned char B64Encoded [256]) - Вы создаете массив из 256 char ptrs, а не 256 символов. – DaveR

+0

Да, спасибо! исправлено его – Rom

1

Похоже, что вы хотели бы использовать что-то вроде этого:

// 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) недостаточно для кодировки base64. Пример выше приведет к переполнению буфера внутри функции Base64Enc() – Rom

+0

Да, мне очень жаль –

1

Это поможет, если вы предоставили ошибку.

я могу, с функцией выше, чтобы это успешно:

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

} 

Вы определенно необходимость таНос пространства для данных. Вам также нужно malloc больше места, чем src (на 1/4 больше, я считаю).

1

кодировки Base64 строки имеет четыре байта на три байта в-строковых данных, так что если srclen 300 байт (или символы), длина для base64 закодированного строки 400.

Wikipedia имеет краткий, но весьма хорошая статья об этом.

Итак, округляя srclen до ближайшего кортежа из трех, разделенного на три, раз четыре должны быть достаточно памяти.

1

Я вижу проблему в вашем коде в том, что она может обращаться к байту после конечного нулевого символа, например, если длина строки равна одному символу. Поведение затем не определено и может привести к возникновению исключения, если проверка границы буфера активирована.

Это может объяснить сообщение, связанное с доступом к неинициализированной памяти.

Затем вы должны изменить свой код, чтобы обрабатывать конечные символы отдельно.

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: Вот википедия страница, описывающая Base64 encoding.

Смежные вопросы