inicialização ponteiro? para uma função específica
-
22-07-2019 - |
Pergunta
Tudo bem, este está me confundindo um pouco.
a seguinte função codifica uma string em base 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;
}
Agora, na função de chamada Base64Enc () eu tenho:
unsigned char *B64Encoded;
Que é o argumento que passar para unsigned char * dest na função de codificação de base 64. Eu tentei diferentes inicializações de mallocs para NULL para outra inicialização. Não importa o que eu faço, eu sempre recebo uma exceção e se eu não inicialize-o, em seguida, o compilador (VS2005 compilador C) lança um aviso a dizer-me que não foi inicializado. Se eu executar esse código com a variável inicializada-un às vezes funciona e alguns outros não. Como faço para inicializar esse ponteiro e passá-lo para a função?
Solução
Você precisa alocar buffer grande o suficiente para conter o resultado codificado. Ou alocá-lo na pilha, como este:
unsigned char B64Encoded[256]; // the number here needs to be big enough to hold all possible variations of the argument
Mas é fácil de causa tampão de estouro de pilha alocando muito pouco espaço usando esta abordagem. Seria muito melhor se você alocá-lo na memória dinâmica:
int cbEncodedSize = srclen * 4 / 3 + 1; // cbEncodedSize is calculated from the length of the source string
unsigned char *B64Encoded = (unsigned char*)malloc(cbEncodedSize);
Não se esqueça de liberar () buffer alocado depois que você fez.
Outras dicas
Parece que você iria querer usar algo como isto:
// 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);
Seria bom se você forneceu o erro.
eu posso, com a sua função acima, para este sucesso:
int main() {
unsigned char *B64Encoded;
B64Encoded = (unsigned char *) malloc (1000);
unsigned char *src = "ABC";
Base64Enc(src, 3, B64Encoded);
}
Você definitivamente necessidade de espaço malloc para os dados. Você também precisa malloc mais espaço do que src (1/4 mais eu acredito).
Uma base 64 cadeia codificada tem quatro bytes por três bytes cadeia no-dados, por isso, se srclen é de 300 bytes (ou caracteres), o comprimento para as base64 cadeia codificada é 400.
Wikipedia tem uma breve mas muito bom artigo sobre ele.
Assim, o arredondamento para cima srclen à tupla mais próximo de três, dividido por três, vezes quatro deve ser memória exatamente o suficiente.
Eu vejo um problema em seu código no fato de que ele pode acessar o byte após o caractere nulo à direita, por exemplo, se o comprimento da corda é um caractere. O comportamento é então indefinido e pode resultar em uma excepção lançada se tampão de controlo de limite é activado.
Isto pode explicar a mensagem relacionada com o acesso à memória não inicializada.
Você deve então alterar o código para que você lidar com os caracteres à direita separadamente.
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: Aqui está uma página da Wikipedia que descreve Base64 codificação .