작성
·
522
0
#include<iostream>
#include<cstring>
#define LENGTH 40
using std::cout;
using std::endl;
class Person {
char* name;
int age;
public:
void SetName(const char* str)
{
// 설정자는 잘못된 값이 설정되는 것을 방지하기위해, 그 값을 먼저 검사한다.
if (!str) return;
// 문자열을 멤버 변수 name에 복사
strncpy(name, str, LENGTH);
}
void SetAge(int n)
{
age = n < 0 ? 0 : n;
}
inline char* GetName(const char* str)
{
return name;
}
inline int GetAge(int n)
{
return age;
}
void Print()
{
cout << "name: " << name << ", age: " << age << endl;
}
};
int main()
{
Person jackson;
Person brown;
Person dean;
// 각 객체의 설정자로 멤버 변수에 값을 설정
jackson.SetName("Michael Jackson");
jackson.SetAge(29);
brown.SetName("Charles Brown");
brown.SetAge(40);
dean.SetName("James Dean");
dean.SetAge(20);
// print out
jackson.Print();
brown.Print();
dean.Print();
return 0;
}
main함수 내에서 Person클래스의 객체 인스턴스들을 만드려는데, 자꾸 저 부분에서 지역변수가 초기화되지 않았다고 하네요... 설정자를 통해서 인스턴스 내 멤버 변수에 값을 대입했는데도 불구하고 말이죠. 정확히 무슨 문제인지 모르겠습니다.
2번째는 C4996코드 오류인데요. strncpy함수가 위험성이 있으니 strncpy_s함수를 대신해서 사용하라고 하는데, 보안의 위험성을 떠나서 strncpy함수를 사용하면 오류가 나는 이유가 있나요
답변 1
0
안녕하세요, 인프런 AI 인턴이에요.
먼저, Person 클래스의 생성자에서 name 멤버 변수에 동적 메모리 할당을 해주지 않아서 생기는 문제입니다. name 포인터가 어디를 가리키는지 모르기 때문에 랜덤한 주소를 가리키게 되면서 지역변수 초기화 오류가 발생합니다. 따라서 생성자에서 name 멤버 변수에 메모리를 동적 할당해주세요.
두번째로, strncpy 함수를 사용하면 발생하는 C4996 코드 오류는 버퍼 오버런(buffer overrun)을 방지하기 위한 대처입니다. strncpy 함수는 복사할 때 버퍼의 크기를 검사하지 않아서 버퍼를 넘어가는 데이터까지 복사해버리는 문제가 발생할 수 있습니다. 따라서 strncpy_s 함수를 사용하면 버퍼 오버런을 방지할 수 있습니다. 하지만, strncpy_s 함수는 C++11부터 표준 스펙으로 지정되었기 때문에 이전 버전의 비주얼 스튜디오에서는 오류 메시지가 나타납니다. 따라서 최신 버전의 비주얼 스튜디오를 사용하시면 정상적으로 작동합니다.
그리고, 멤버 변수를 반환할 때도 char* 타입으로 반환하지 않고 const char* 로 반환해주세요. 그리고 inline 함수에는 정의와 선언을 모두 헤더 파일에 작성해야합니다.
아래는 수정된 코드입니다.
#include
#include
#define LENGTH 40
using std::cout;
using std::endl;
class Person {
char* name;
int age;
public:
Person() { name = new charLENGTH; } // 생성자에서 name 멤버 변수에 동적 메모리 할당
~Person() { delete[] name; } // 소멸자에서 할당된 메모리를 해제
void SetName(const char* str)
{
if (!str) return;
strncpy(name, str, LENGTH-1);
name[LENGTH-1] = 0; // 널 문자 추가
}
void SetAge(int n)
{
age = n < 0 ? 0 : n;
}
inline const char* GetName() const // 반환 타입을 수정하고 매개변수를 제거
{
return name;
}
inline int GetAge() const // 반환 타입을 수정하고 매개변수를 제거
{
return age;
}
void Print()
{
cout << "name: " << name << ", age: " << age << endl;
}
};
int main()
{
Person jackson;
Person brown;
Person dean;
jackson.SetName("Michael Jackson");
jackson.SetAge(29);
brown.SetName("Charles Brown");
brown.SetAge(40);
dean.SetName("James Dean");
dean.SetAge(20);
jackson.Print();
brown.Print();
dean.Print();
return 0;
}