Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 变量周围的堆栈已损坏c++; Contact::Contact(常量字符*name2,常量长*phone2,int num2){ bool-safe=name2==nullptr&&phone2==nullptr&&num2==0; 如果(安全){ *这=触点(); } 否则{ strcpy(名称,名称2); 名称[19]=“0”; bool valid=phone2!=nullptr&&num2>0; 如果(有效){ 整数计数=0; 对于(int i=0;i1000000000ll&&phone2[i]_C++ - Fatal编程技术网

C++ 变量周围的堆栈已损坏c++; Contact::Contact(常量字符*name2,常量长*phone2,int num2){ bool-safe=name2==nullptr&&phone2==nullptr&&num2==0; 如果(安全){ *这=触点(); } 否则{ strcpy(名称,名称2); 名称[19]=“0”; bool valid=phone2!=nullptr&&num2>0; 如果(有效){ 整数计数=0; 对于(int i=0;i1000000000ll&&phone2[i]

C++ 变量周围的堆栈已损坏c++; Contact::Contact(常量字符*name2,常量长*phone2,int num2){ bool-safe=name2==nullptr&&phone2==nullptr&&num2==0; 如果(安全){ *这=触点(); } 否则{ strcpy(名称,名称2); 名称[19]=“0”; bool valid=phone2!=nullptr&&num2>0; 如果(有效){ 整数计数=0; 对于(int i=0;i1000000000ll&&phone2[i],c++,C++,这是我的3个参数构造函数。我不断收到错误消息,变量周围的堆栈已损坏。但是当我去掉第3行中的name2==nullptr时,它可以正常工作(尽管输出与我想要的不完全一样)。我做错了什么?让我们假设name2==nullptr,但是phone2!=空PTR。这意味着save将为false,并且将执行strcpy(name,name2),它将尝试从null ptr复制。根据操作系统的不同,这可能会导致访问冲突(禁止对地址0进行读取访问),也可能不会。我的猜测是,允许读访问 因此,strcpy将尝试在地

这是我的3个参数构造函数。我不断收到错误消息,变量周围的堆栈已损坏。但是当我去掉第3行中的
name2==nullptr
时,它可以正常工作(尽管输出与我想要的不完全一样)。我做错了什么?

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

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

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

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

但您的代码通常非常糟糕(意味着不安全、容易出错)

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

删除条件
name2==nullptr
使代码进入安全路径,在该路径中,即使
name2!=空PTR

如果
name2!=nullptr
然后使用
name2==nullptr
进入
else
部分,在那里有此代码

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;
        }
    }

}
我想我的名字是

    strcpy(name, name2);
    name[19] = '\0';
那么代码应该是

    constexpr int maxNameLength = 20;
    char name[maxNameLength]; // if this is just a pointer you got other problems.
在我开始使用
std::string
std::vector
std::array
之后,我遇到的问题要少得多


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

Read。使用所有警告和调试信息编译:
g++-Wall-Wextra-g
with。然后是。您的问题没有任何内容,因此我们无法重现您的问题Stack Overflow不是免费的调试服务,您应该展示您尝试使用调试器或其他更简单的方法(如调试打印语句)调试代码的情况。您还可以分别测试代码的每一部分,以准确地找出导致问题的代码的哪一部分,并做出正确的判断。这并不是你唯一一次在代码中遇到bug,学习调试程序比让别人帮你找到bug更有帮助。还可以阅读有关的文章。它可能是相关的(但由于我们没有任何,我们不能确定)
strcpy(name,name2);名称[19]=“0”--为什么不使用
std::string
?这样的代码可能会导致“堆栈周围变量已损坏”错误应该怎么做?你不能做那种事!这确实是定义的行为,我宁愿在头中初始化我的成员,所以您只需执行“return”,但在构造函数中调用时,
*this=Contact()
可以吗?我不这么认为,但标准可能会说相反。但是该对象尚未完全构造,因此调用
操作符=
可能不安全。想象一个带有指针变量的对象。
操作符=
可能会释放当前指针并创建另一个指针的深度副本。但是当调用
operator=
时,当前指针可能尚未初始化。这就是为什么我认为在构造函数中调用this=Contact()
是错误的。
    strncpy(maxNameLength, name, name2);
    name[maxNameLength-1] = '\0';