【问题标题】:Program crashes when deleting dynamic cstring [closed]删除动态 cstring 时程序崩溃 [关闭]
【发布时间】:2018-05-07 03:24:33
【问题描述】:

我正在开展一个需要使用动态分配的 cstrings 的学校项目。在我的代码中,我有一个临时的 cstring,但每当我尝试删除它时它就会崩溃。

这是我的代码:

#include "group.h"
#include <iostream>

using namespace std;

void addGroup()
{

    group *newGroup = new group;
    char tempString[ARRAY_CONST];

    cin >> option;
    cin.ignore(100, '\n');

    if (option == 'Y' || option == 'y')
    {
        cout << "Enter name: ";

        cin.getline(tempString, ARRAY_CONST, '\n');
        char *tempName = new char[strlen(tempString + 1)];
        strcpy(tempName, tempString);

        cout << "Enter email: ";
        cin.getline(tempString, ARRAY_CONST, '\n');

        newGroup->setPromo(true, tempName, tempString);

        delete[] tempName;
    }
}

每当它到达“delete[] tempName”时程序就会崩溃,这可能是编译器优化的副作用吗?

已编辑:

我不确定在不添加太多代码的情况下应该包含多少代码,但这里是 setPromo():

bool group::setPromo(bool enroll, const char *name, const char *email)
{
    promo.enrolled = enroll;

    if (promo.name)
        delete[] promo.name;

    promo.name = new char[strlen(name) + 1];
    strcpy(promo.name, name);

    if (promo.email)
        delete[] promo.email;

    promo.email = new char[strlen(email) + 1];
    strcpy(promo.email, email);

    return true;
}

这个组类有私有数据成员:

struct promotion
{
    bool enrolled;
    char *name;
    char *email;
} promo;

group 类有一个处理 newGroup 的析构函数。

再次编辑:

好的,我已经弄清楚了,但我不明白为什么?在包含以下内容的行上:

char *tempName = new char[strlen(tempString + 1)];

我已将其更改为:

char *tempName = new char[strlen(tempString) + 1];

我从 strlen() 括号中取出“1”。

为什么会有不同?这里发生了什么?

【问题讨论】:

  • 我怀疑 Ninjas 攻击并杀死了setPromo 中的分配。通过发布minimal reproducible example 来证明我错了。
  • 我不确定在不添加太多代码的情况下应该包含多少代码minimal reproducible example 总结了一下。
  • ARRAY_CONST 是什么?编辑您的问题以包含minimal reproducible example
  • 您的动态操作和复制比您需要的要多得多。程序分配tempName 并将tempString 复制到其中。然后它为promo.name 分配存储空间并将tempName 复制到其中。看到这里的怪事了吗?最好的选择是使用std::string,但如果没有,请考虑使用 2 个巧妙命名的tempStrings 并为promo.namepromo.email 分配存储空间,然后复制这两个tempStrings。少分配少复制。
  • 我想我会这样做,谢谢你的建议。

标签: c++ memory dynamic c-strings


【解决方案1】:

显然不是因为delete[]。您需要进入setPromo。最后你错过了函数末尾的delete newGroup;。 “dgsomerton”提出了一个很好的观点:

char *tempName = new char[strlen(tempString + 1)];

这实际上导致比需要的少两个字节和缓冲区溢出。随机错误并不奇怪。修复:

char *tempName = new char[strlen(tempString)+1];

这就是为什么我更喜欢std::string 而不是char*

【讨论】:

  • 如果我注释掉“delete[] tempName”,程序不会崩溃并且会继续运行,但是会出现内存泄漏。
  • 运行时错误有恶行;症状往往出现得太晚。除非对“setPromo”进行分析,否则无法再说什么。虽然不合逻辑,但我猜该函数甚至可能正在删除指针。
  • 这段代码错误 "char *tempName = new char[strlen(tempString + 1)];"它会将 tempString 的地址加 1 到该地址,并在该地址上执行 strlen()。答案将是一些随机数(可能比要求的小),因此您写入未分配的内存,可能会破坏您的堆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-02
  • 1970-01-01
  • 2012-11-06
  • 2013-12-12
  • 1970-01-01
相关资源
最近更新 更多