【问题标题】:Pointer initializiation? for a specific function指针初始化?对于特定功能
【发布时间】:2009-06-24 21:18:55
【问题描述】:

好吧,这个让我有点困惑。

以下函数将字符串编码为 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;
}

现在,在调用 Base64Enc() 的函数上,我有:

unsigned char *B64Encoded;

我在 base 64 编码函数中传递给 unsigned char *dest 的参数是什么。 我尝试了从 mallocs 到 NULL 到其他初始化的不同初始化。无论我做什么,我总是会得到一个异常,如果我不初始化它,那么编译器(VS2005 C 编译器)会抛出一个警告,告诉我它没有被初始化。 如果我使用未初始化的变量运行此代码,有时它可以工作,而其他一些则不能。 如何初始化该指针并将其传递给函数?

【问题讨论】:

    标签: c pointers initialization base64


    【解决方案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);
    

    完成后不要忘记释放()分配的缓冲区。

    【讨论】:

    • 您的第一个示例 (unsigned char* B64Encoded[256];) 是错误的 - 它应该是:(unsigned char B64Encoded[256]) - 您正在创建一个包含 256 个字符的数组,而不是 256字符。
    【解决方案2】:

    看起来你想要使用这样的东西:

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

    【讨论】:

    • (srclen + 1) 不足以进行 base64 编码。上面的例子会导致 Base64Enc() 函数内部的缓冲区溢出
    【解决方案3】:

    如果您提供错误信息会有所帮助。

    有了你上面的功能,我可以成功:

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

    肯定需要为数据分配空间。您还需要 malloc 比 src 更多的空间(我相信多 1/4)。

    【讨论】:

      【解决方案4】:

      base64 编码字符串每三个字节的数据字符串有四个字节,因此如果 srclen 为 300 个字节(或字符),则 base64 编码字符串的长度为 400。

      Wikipedia 有一篇简短但相当不错的文章。

      因此,将 srclen 向上取整到最接近的三元组,除以三,乘以四应该正好足够内存。

      【讨论】:

        【解决方案5】:

        我在您的代码中发现了一个问题,即它可能会访问尾随空字符之后的字节,例如,如果字符串长度为一个字符。然后该行为未定义,如果激活缓冲区边界检查,则可能导致抛出异常。

        这可以解释与访问未初始化内存相关的消息。

        然后您应该更改您的代码,以便单独处理尾随字符。

        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 的维基百科页面。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-09
          • 2011-04-10
          • 2012-10-27
          相关资源
          最近更新 更多