【问题标题】:Proper Way To Initialize Unsigned Char*初始化无符号字符的正确方法*
【发布时间】:2011-06-20 01:01:16
【问题描述】:

初始化unsigned char* 的正确方法是什么?我目前正在这样做:

unsigned char* tempBuffer;
tempBuffer = "";

或者我应该使用memset(tempBuffer, 0, sizeof(tempBuffer)); 吗?

【问题讨论】:

  • 变量名错误。它不是缓冲区,只是一个指针。使用 unsigned char tempBuffer[666] 创建一个缓冲区;

标签: c++ c char unsigned


【解决方案1】:

这取决于您想要实现的目标(例如,您是否想要修改字符串)。参见例如http://c-faq.com/charstring/index.html 了解更多详情。

注意,如果你声明一个指向字符串字面量的指针,它应该是const,即:

const unsigned char *tempBuffer = "";

【讨论】:

  • 如果我把它设为const,但我以后不能添加它...应该一直是const吗?
  • @Brian: 如果它指向一个字符串字面量,它应该是 const。
  • @Brian:如果您打算“稍后添加”,您需要将您的tempBuffer 指向实际的内存缓冲区,而不是文字字符串。
  • @Fred:我明白了。所以如果我从unsigned char *tempBuffer = "I am a beautiful banana" 开始,那么它就是const。否则,如果我将在以后的例程中向它添加字节,那么非常量就可以了,对吗?
  • @Brian:声明一个指针不会分配任何空间来通过该指针写入,除非你用一个文字字符串初始化它,在这种情况下它有那么多字节(+ 1 来保存终止的 0 字节)分配的应该被视为只读的。这意味着无论如何您都不能添加到声明为指针的字符串的末尾,除非您首先将其指向内存的有效区域(数组或使用malloc() 动态分配的内存)。
【解决方案2】:

因为它是一个指针,你要么想像这样先将它初始化为 NULL:

unsigned char* tempBuffer = NULL;
unsigned char* tempBuffer = 0;

或者分配一个变量的地址,像这样:

unsigned char c = 'c';

unsigned char* tempBuffer = &c;

编辑: 如果你想分配一个字符串,可以这样做:

unsigned char myString [] = "This is my string";
unsigned char* tmpBuffer = &myString[0];

【讨论】:

  • 值得澄清的是,您的第二个示例将为您提供指向有效字符的有效指针,但它不适用于标准字符串函数(即使类型相同),因为字符串函数需要一个指针指向一个以 nul 结尾的字符数组,而不是指向单个字符的指针。我的猜测是 OP 对使用字符串感兴趣。
  • 谢谢蒂姆。相应地进行了编辑。
【解决方案3】:

第二种方法会给你一个空指针。请注意,您在这里并没有为缓冲区声明任何空间,而是声明了一个指向必须在其他地方创建的缓冲区的 pointer。如果你将它初始化为"",这将使指针指向一个只有一个字节的静态缓冲区——空终止符。如果您想要一个可以稍后写入字符的缓冲区,请使用 Fred 的数组建议或类似 malloc 的内容。

【讨论】:

  • 所以在您看来,malloc(24);(或某个数字)比将其设置为 ""0NULL 更可取?
  • @Brian:我怀疑有人可以在不知道您想要实现什么的情况下回答。但是,您似乎确实需要分配一些内存。在这种情况下,当您不再需要它时,千万不要忘记free()
  • @Brian:通常在编译时未知您需要的最大大小时使用malloc,因此您首先将其设置为NULL,然后设置为malloc,与您一样多当你知道大小时需要。当大小相对较小且固定时,最好分配数组,因为您不必担心释放内存,但如果您尝试将其从函数中返回,则会导致问题。就像@ereOn 说的那样,如果您需要准确的建议,我们确实需要有关您正在尝试做什么的更多详细信息。
  • @Karl:我在这里使用 SHA1 实现:tamale.net/sha1/sha1-0.2,我从getDigest() 返回一个unsigned char*。在调用getDigest() 之前,我必须声明一个unsigned char*
  • @Brian,在这种情况下,您甚至根本不需要初始化它,尽管如果您要提前声明它,最好将它分配给NULL。我可能会在一行中完成所有操作:unsigned char* digest = sha1ObjectPtr->getDigest();
【解决方案4】:

如果计划将其用作缓冲区,并且您想稍后将其移动以指向某个内容,则将其初始化为 NULL,直到它真正指向您要写入的某个位置,而不是空字符串。

unsigned char * tempBuffer = NULL;
std::vector< unsigned char > realBuffer( 1024 );
tempBuffer = &realBuffer[0]; // now it really points to writable memory
memcpy( tempBuffer, someStuff, someSizeThatFits );

【讨论】:

    【解决方案5】:

    答案取决于您使用 unsigned char 的目的。 char 什么都没有,只是一个小整数,在 99% 的实现中大小为 8 位。

    C 恰好有一些字符串支持非常适合 char,但这并不限制 char 对字符串的使用。


    初始化指针的正确方法取决于 1) 其范围和 2) 其预期用途。

    如果指针被声明为静态的,和/或在文件范围内声明,那么 ISO C/C++ 保证它被初始化为 NULL。编程风格纯粹主义者仍然会将其设置为 NULL 以保持其风格与局部范围变量一致,但理论上这样做是没有意义的。

    至于将其初始化为...将其设置为NULL。不要将它设置为指向“”,因为这将分配一个包含空终止的静态虚拟字节,一旦将指针分配给其他东西,这将成为一个很小的静态内存泄漏。

    有人可能会质疑,为什么您首先需要将其初始化为任何东西。只需在使用前将其设置为有效的值。如果你担心在给它一个有效值之前使用一个指针,你应该得到一个合适的静态分析器来发现这些简单的错误。甚至大多数编译器都会发现这个错误并给你一个警告。

    【讨论】:

      【解决方案6】:

      要“正确”初始化一个指针(unsigned char * 如您的示例),您只需要做一个简单的操作

      unsigned char *tempBuffer = NULL;
      

      如果要初始化unsigned chars 的数组,可以执行以下任一操作:

      unsigned char *tempBuffer = new unsigned char[1024]();
      // and do not forget to delete it later
      delete[] tempBuffer;
      

      unsigned char tempBuffer[1024] = {};
      

      我还建议您查看std::vector&lt;unsigned char&gt;,您可以像这样初始化它:

      std::vector<unsigned char> tempBuffer(1024, 0);
      

      【讨论】:

        【解决方案7】:

        如果你在编译时就知道缓冲区的大小:

        unsigned char buffer[SIZE] = {0};
        

        对于动态分配的缓冲区(在运行时或在上分配的缓冲区):

        1.首选new运算符:

        unsigned char * buffer = 0;  // Pointer to a buffer, buffer not allocated.
        buffer = new unsigned char [runtime_size];
        

        2.许多“初始化”或填充简单值的解决方案:

        std::fill(buffer, buffer + runtime_size, 0); // Prefer to use STL
        memset(buffer, 0, runtime_size);
        for (i = 0; i < runtime_size; ++i) *buffer++ = 0;  // Using a loop
        

        3.C语言侧提供了一次调用的分配和初始化。
        但是,该函数不调用对象的构造函数:

        buffer = calloc(runtime_size, sizeof(unsigned char))
        

        请注意,这也会将缓冲区中的所有位设置为零;你在初始值中没有选择。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-11
          • 2020-04-21
          • 2013-01-30
          相关资源
          最近更新 更多