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
时,它可以正常工作而不会出现错误(尽管输出并不完全符合我的要求)。我在那里做错了吗?
答案 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::string
,std::vector
和std::array
之后,我遇到的问题要少得多了。
我没有看到其余的代码,我猜您的类正在使用指针,因此需要复制构造函数和复制赋值(以及move变体)。