【问题标题】:Unable to delete object that used strcpy()无法删除使用 strcpy() 的对象
【发布时间】:2017-04-19 22:13:04
【问题描述】:

最近我在删除一个对象时会抛出一个异常,我已将其范围缩小到使用 strcpy()。为了测试这一点,我做了一个简单的测试类,它(基本上)只使用 strcpy() 和瞧,一个例外。

#pragma once
class TestClass
{
public:
    TestClass(char []);
    ~TestClass();

    char teststring[];
};

它的构造函数是这样的:

TestClass::TestClass(char incstring[])
{
    strcpy(teststring, incstring);
    printf(teststring);
}

如果我运行以下代码:

int main(){
    TestClass* test = new TestClass("Cheezit");

    delete test;
}

我得到一个抛出的异常! STRCPY() 发生了什么??!?!?!?!

注意:控制台窗口会打印“Cheezit”。

【问题讨论】:

  • 这不是一个有效的类定义。您的代码不是有效的 C++;使用损坏的编译器(或以损坏的方式使用编译器)很不幸,它可以让您逃脱惩罚。
  • 请编辑您的问题以包含minimal reproducible example
  • @Slava:它被称为“flexible array member”。您只能在动态分配上下文中使用它。
  • 该代码不是 MCVE,因为它缺少所需的#includes 和~TestClass 的定义。
  • 不能在 gcc ideone.com/Z1JY2J上编译

标签: c++ exception memory strcpy


【解决方案1】:

您的代码不是有效的 C++。在 C++ 中,所有非静态类数据成员都必须具有 complete 类型,而char[] 不是完整类型。您需要指定数组大小,然后相应地初始化数组:

class TestClass
{
public:
    TestClass(char a[]) : teststring{} { std::strncpy(teststring, a, 2); }
    char teststring[3];
};

您不能从任何构造函数中推断出数组大小,因为构造函数是类的一部分,并且在指定数组大小之前类是不完整的。

【讨论】:

  • 使用 C++17,他可以将其设为模板类并推断其大小:en.cppreference.com/w/cpp/language/class_template_deduction
  • @JerryJeremiah:当然,但那是完全不同的东西......(而且你不会推断出构造函数参数 value!)
  • @KerrekSB 谢谢,我已经将 teststring 更改为 char 指针 (char*),在 TestClass 的构造函数中,我在 strcpy() 之前有一行:“teststring = new char[sizeof( incstring)];"。这会使 teststring 指向一个大小为 incstring 的数组吗?这个内存安全吗?
  • @DanielOelbaum:这些都不是。你说的每一件事都有一个错误。更新您的问题,我可以指出它们。或者只是看看这个网站,搜索“array size”和“sizeof”。并查看以 null 结尾的字符串是如何工作的以及 strcpy 是如何工作的。
  • 我做了一些研究,认为我已经取得了一些进展。我在stackoverflow.com/questions/43531933/… 发布了另一个问题。如果你们中的任何人可以帮助我,我将不胜感激
【解决方案2】:
char teststring[];

标准 C++ 中不允许作为数组成员。

您的编译器似乎将其视为灵活数组成员,这是 C 的一项功能,是 C++ 的扩展。但是,正确使用灵活数组成员需要注意分配,而您尚未这样做。所以即使假设有一些这样的扩展,你的程序仍然有未定义的行为。

【讨论】:

    猜你喜欢
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 2021-12-29
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多