变量周围的堆栈损坏了C ++

时间:2018-07-01 04:44:26

标签: c++

Contact::Contact(const char* name2, const long long * phone2, int num2) {

    bool safe = name2== nullptr && phone2 == nullptr && num2 == 0;

    if (safe) {

        *this = Contact();

    }
    else {
        strcpy(name, name2);
        name[19] = '\0';
        bool valid = phone2 != nullptr && num2 > 0;
        if (valid) {
            int count = 0;

            for (int i = 0; i < num2; i++) {
                valid = phone2[i] > 10000000000LL && phone2[i] < 999999999999LL;  // PROBABLY A GOOD IDEA TO MAKE A FUNCTION TO CHECK VALIDNESS
                if (valid) count++;
            }

            num = count;
            phone = new long long[num];

            for (int i = 0, j = 0; i < num2; i++) {
                if (phone2[i] > 10000000000LL && phone2[i] < 999999999999LL) {
                    phone[j] = phone2[i];
                    j++;
                }
            }
        }
        else {
            num = 0;
            phone = nullptr;
        }
    }

}

这是我的3个参数构造函数。我不断收到错误消息,该变量周围的堆栈已损坏。但是,当我摆脱第3行中的name2==nullptr时,它可以正常工作而不会出现错误(尽管输出并不完全符合我的要求)。我在那里做错了吗?

2 个答案:

答案 0 :(得分:0)

让我们假设name2 == nullptr,但是phone2 != nullptr。这意味着save将为false,并且strcpy(name, name2)将被执行,这将尝试从nullptr复制。根据操作系统的不同,这可能会给您带来访问冲突(禁止对地址0的读取访问),也可能不会。我的猜测是,允许读取访问。

因此strcpy将尝试在地址0处复制一个完全伪造的字符串。它将复制char直到遇到\0字符。

这几乎在所有情况下都比成员变量name长,从而覆盖那里的内存。

如果将save = stuff && stuff更改为save = name2==nullptr || phone2==nullptr,该错误可能会消失。

但是您的代码通常很糟糕(意味着不安全,容易出错)。

您不应再在2018年使用strcpy。使用std :: string代替。 使用* this = Contact()可能是错误的。您正在之前完全构造对象,在此处(operator=处调用赋值运算符。

答案 1 :(得分:0)

删除条件name2== nullptr使代码进入安全的路径,即使name2 != nullptr,您也会获得默认的构造联系人。

如果name2 != nullptr,那么您和name2 == nullptr一起进入else部分,那里有此代码

    strcpy(name, name2);
    name[19] = '\0';

我认为名字是

    constexpr int maxNameLength = 20;
    char name[maxNameLength]; // if this is just a pointer you got other problems.

然后该代码应为

    strncpy(maxNameLength, name, name2);
    name[maxNameLength-1] = '\0';

在我开始使用std::stringstd::vectorstd::array之后,我遇到的问题要少得多了。

我没有看到其余的代码,我猜您的类正在使用指针,因此需要复制构造函数和复制赋值(以及move变体)。