【问题标题】:C++ strcpy non-constant expression as array boundC++ strcpy 非常量表达式作为数组绑定
【发布时间】:2010-01-24 17:25:37
【问题描述】:

在 C#、PHP 和其他东西上玩了很长时间后,我又回到了 C++,我发现了一些奇怪的东西:

temp.name = new char[strlen(name) + strlen(r.name) + 1];

这编译

temp.name = (char *)malloc(sizeof(char[strlen(name) 
     + strlen(r.name) + 1]));

这不是(temp.name 是一个字符 *)

编译错误是

错误 C2540:非常量表达式 作为数组绑定

有谁知道问题可能是什么以及如何解决?谢谢。

【问题讨论】:

  • 如果您使用 C++,请忘记 char 数组并使用 std::string。
  • 虽然程序文本看起来相同,但语义却大不相同。 C++ 中有 数组类型的大小为零或运行时值。但是这些数组类型只能由new-type-id 寻址。声明数组的类型说明符不使用新类型 ID,因此它们无法表示这些“花哨”类型。尝试编写 new (char[strlen(name)]);new (char[0]); 并注意使用符合标准的编译器也会失败:因为括号会使编译器形成 type-id 而不是 new-type-id。类似地,sizeof 需要 type-id

标签: c++ arrays pointers character


【解决方案1】:

sizeof(...) 需要一个常量编译时表达式。 strlen 不是编译时表达式,它是一个需要执行才能得到结果的函数。因此,编译器无法为这样声明的数组保留足够的存储空间:

char c[strlen("Hello")];

虽然字符串的长度明明是5,但是编译器并不知道。

为避免此陷阱,请勿在此处使用sizeof。而是:

char* c = (char*)malloc(strlen(name)+strlen(rname)+1);

这会给你一个指向 n 字节的指针作为回报。 sizeof(char)==1 始终为真,因此缓冲区中的字节数等于您可以在其中存储的字符数。要malloc 不同类型的数组,乘以一个数组元素的静态大小:

int* c = (int*) malloc(sizeof(int)*100);

这没关系,因为sizeof 应用于编译时表达式。当然,C++ 的方式要干净得多:

int* c = new int[100];

【讨论】:

    【解决方案2】:

    问题在于char[...],它是一种数组类型,在 C++(和 C89)中,数组大小需要是编译时常量。您可能应该使用 std::string 而不是通过new[]malloc() 手动分配内存,但如果您更喜欢使用手动分配,请直接将大小计算为字符数而不是使用数组和sizeof去做吧。

    【讨论】:

      【解决方案3】:

      malloc 需要一个 size_t 作为其输入,这意味着您需要计算实际大小并将其传入,而不是指定类型:

      temp.name = (char *) malloc( (strlen(name) + strlen(r.name) + 1)) * sizeof(char));
      

      无论如何,您可能应该使用new,所以我没有发现任何实际问题。

      【讨论】:

      • 1 == sizeof(char) 总是正确的,所以你不需要乘以它。
      • 我知道,但我习惯性地这样做,以防我以后想更改类型(可能是宽字符类型?)。然后我可以在 vim 中执行类似 ":s/char/wchar_t/g" 的操作,一切都会自动修复。 :-)
      • 如果这是本意,那么最好使用sizeof *temp.name
      • 嗯...事实上,这是一个很好的观点。在我的情况下,为了清楚起见,我习惯性地使用类型(即,如果你试图做一个背面的信封,你不必再次检查变量的类型以获得实际大小内存估计),但这同样有效,我没有任何真正好的理由不这样做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      相关资源
      最近更新 更多