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]
这是我的3个参数构造函数。我不断收到错误消息,变量周围的堆栈已损坏。但是当我去掉第3行中的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将尝试在地
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';