【问题标题】:Passing structure by reference and assign string通过引用传递结构并分配字符串
【发布时间】:2015-03-05 20:13:36
【问题描述】:

这是一个简单的程序,我试图通过引用和字符串将结构传递给函数。该函数应该检测字符串的长度并将其分配给结构的成员。这是程序:

#include <iostream>
#include <string.h>

struct stringy   // structure definition
{
    char *str;
    int ct;
};

void set(stringy &beany, const char *testing);   // function definition

int main()
{
    stringy beany;
    char testing[] = "Reality isn't what it used to be.";
    set(beany, testing);   // function call
    return 0;
}

void set(stringy &beany, const char *testing)   // function prototype
{
    int i=0;
    while (*(testing+i) != '\0')    // this loop counts the number of characters
    {
        i++;
        std::cout << i << "\n";
    }
    beany.str = new char[i];    // dynamic storage allocation
    std::cout << strlen(beany.str);   // printing the length of the string
}

由于某种原因,函数 set() 的最后一行的输出是 47,而“i”的值是 33。最后 15 个字节被垃圾值填充。我希望beany.str的长度应该等于*testing的长度。

【问题讨论】:

    标签: c++ function pointers structure


    【解决方案1】:

    您为beany.str 分配内存,但您没有初始化该内存。未进行任何初始化的分配内存的内容是不确定的(实际上看起来是随机的)。

    另外不要忘记旧的 C 风格字符串需要以特殊的 '\0' 字符终止(或者像 strlen 这样的函数将不起作用)。

    这两个问题,使用未初始化的内存和忘记终止符,都会导致undefined behavior

    【讨论】:

      【解决方案2】:
      beany.str = new char[i];    // dynamic storage allocation
      std::cout << strlen(beany.str);   // printing the length of the string
      

      strlen 查找终止空字符 '\0'。在beany.str 中没有一个保证,因为您将new char[i] 的结果分配给它,它不会对元素进行零初始化。它为未初始化为零i字符分配空间。

      即使它们是,strlen 也会返回 0,因为它会立即在第一个位置找到 '\0'。如果您自己不记得i,尺寸信息将会丢失。

      查看以下程序的输出:

      #include <iostream>
      
      int main()
      {
          char *str = new char[100];
          for (int i = 0; i < 100; ++i)
          {
              std::cout << str[i] << "\n";
          }
      }
      

      行为未定义。您将可能看到一些看似随机的字符。

      如果您想要零初始化,请使用new char[i]()

      但是,strlen 仍然是 0:

      #include <iostream>
      #include <string.h>
      
      int main()
      {
          char *str = new char[100]();
          for (int i = 0; i < 100; ++i)
          {
              std::cout << str[i] << "\n";
          }
      
          std::cout << strlen(str) << "\n";
      }
      

      你应该摆脱 array-new 和 array-delete。使用std::string

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-04
        • 2017-01-27
        • 2014-08-11
        • 2017-07-25
        • 2016-07-05
        • 2013-04-07
        • 2018-09-01
        • 2013-05-12
        相关资源
        最近更新 更多