如何修复此代码中的 'Access violation reading location'
how to fix 'Access violation reading location' in this code
运行这段代码我遇到了这样的错误
' Project1.exe 中的 0x778D7FCB (ntdll.dll) 处抛出异常:0xC0000005:访问冲突读取位置 0x00000014。'
此行出现此错误
~UnivStudnet() {
delete[]major; // error
}
#include <iostream>
#include <cstring>
using namespace std;
class Person {
private:
char * name;
public:
Person(const char * myname) {
name = new char[strlen(myname) + 1];
strcpy_s(name, strlen(name), myname);
}
~Person() {
delete[]name;
}
void WhatYourName() const {
cout << "My name is " << name << endl;
}
};
class UnivStudnet : public Person {
private:
char * major;
public:
UnivStudnet(const char * myname, const char * const mymajor) :Person(myname) {
major = new char[strlen(mymajor) + 1];
strcpy_s(major, strlen(major), mymajor);
}
~UnivStudnet() {
delete[]major;
}
void WhoAreYou() const {
WhatYourName();
cout << "My major is " << major << endl;
}
};
int main(void) {
UnivStudnet st1("kim", "Mathenatics");
st1.WhoAreYou();
UnivStudnet st2("hong", "Physiscs");
st2.WhoAreYou();
return 0;
}
如何修复此错误?
你可以使用更多 C++ 方式:
您需要申报:
virtual ~Person()
基础 class 中的析构函数,然后:
class UnivStudnet : public Person {
private:
std::string major;
public:
UnivStudnet(const char * myname, const char * const mymajor) :Person(myname), major(mymajor) {
}
virtual ~UnivStudnet() {
}
...
这样你就可以实现你所需要的,而不用考虑内存allocation/deallocation。记得#include <string>
header.
在 Person
class.
中使用相同的方法
两条 strcpy_s
行有错误。
strcpy_s(name, strlen(name), myname);
应该是
strcpy_s(name, strlen(myname)+1, myname);
同样
strcpy_s(major, strlen(major), mymajor);
应该是
strcpy_s(major, strlen(mymajor)+1, mymajor);
在具有不确定值的新分配的字符数组 name
和 major
上调用 strlen
会导致未定义的行为,这就是导致崩溃的原因。
您的 strcpy_s 用法值得怀疑。
major = new char[strlen(mymajor) + 1];
strcpy_s(major, strlen(major), mymajor);
strcpy_s
的第二个参数是由第一个参数指定的缓冲区的分配大小。 (我刚刚意识到 - 基于另一个答案 strlen(major)
在你复制到它之前是未定义的!
您分配的缓冲区足够大以容纳字符串,但随后对 strcpy_s 的调用表明 major
不足以容纳包括 null 在内的整个字符串字符
更好:
size_t len = strlen(mymajor) + 1;
major = new char[len];
strcpy_s(major, len, mymajor);
对基础 class name
参数也重复上述模式。
运行这段代码我遇到了这样的错误
' Project1.exe 中的 0x778D7FCB (ntdll.dll) 处抛出异常:0xC0000005:访问冲突读取位置 0x00000014。'
此行出现此错误
~UnivStudnet() {
delete[]major; // error
}
#include <iostream>
#include <cstring>
using namespace std;
class Person {
private:
char * name;
public:
Person(const char * myname) {
name = new char[strlen(myname) + 1];
strcpy_s(name, strlen(name), myname);
}
~Person() {
delete[]name;
}
void WhatYourName() const {
cout << "My name is " << name << endl;
}
};
class UnivStudnet : public Person {
private:
char * major;
public:
UnivStudnet(const char * myname, const char * const mymajor) :Person(myname) {
major = new char[strlen(mymajor) + 1];
strcpy_s(major, strlen(major), mymajor);
}
~UnivStudnet() {
delete[]major;
}
void WhoAreYou() const {
WhatYourName();
cout << "My major is " << major << endl;
}
};
int main(void) {
UnivStudnet st1("kim", "Mathenatics");
st1.WhoAreYou();
UnivStudnet st2("hong", "Physiscs");
st2.WhoAreYou();
return 0;
}
如何修复此错误?
你可以使用更多 C++ 方式:
您需要申报:
virtual ~Person()
基础 class 中的析构函数,然后:
class UnivStudnet : public Person {
private:
std::string major;
public:
UnivStudnet(const char * myname, const char * const mymajor) :Person(myname), major(mymajor) {
}
virtual ~UnivStudnet() {
}
...
这样你就可以实现你所需要的,而不用考虑内存allocation/deallocation。记得#include <string>
header.
在 Person
class.
两条 strcpy_s
行有错误。
strcpy_s(name, strlen(name), myname);
应该是
strcpy_s(name, strlen(myname)+1, myname);
同样
strcpy_s(major, strlen(major), mymajor);
应该是
strcpy_s(major, strlen(mymajor)+1, mymajor);
在具有不确定值的新分配的字符数组 name
和 major
上调用 strlen
会导致未定义的行为,这就是导致崩溃的原因。
您的 strcpy_s 用法值得怀疑。
major = new char[strlen(mymajor) + 1];
strcpy_s(major, strlen(major), mymajor);
strcpy_s
的第二个参数是由第一个参数指定的缓冲区的分配大小。 (我刚刚意识到 - 基于另一个答案 strlen(major)
在你复制到它之前是未定义的!
您分配的缓冲区足够大以容纳字符串,但随后对 strcpy_s 的调用表明 major
不足以容纳包括 null 在内的整个字符串字符
更好:
size_t len = strlen(mymajor) + 1;
major = new char[len];
strcpy_s(major, len, mymajor);
对基础 class name
参数也重复上述模式。