C++ 클래스 인스턴스의 지역변수 초기화 오류 & C4996 에러
643
작성한 질문수 1
#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;
}
5-B
0
5
1
20년 4,5회 13번
0
18
1
11강 CallOrRegister_OnExperienceLoaded 질문
0
28
1
4 - A
0
31
2
코딩살구클럽 입장이 안됩니다
0
79
2
강의자료는 어디서 받을 수 있죠?
1
35
2
4-F 경우의 수 질문입니다.
0
35
2
코딩살구클럽 가입이 안됩니다.
0
81
2
살구 클럽에 대한 질문있습ㄴ디ㅏ
0
61
1
교안 158페이지 문의드립니다
0
46
2
코딩살구클럽 관련 건의사항
0
119
1
코살에 19942 다이어트 문제에 N의 범위가 빠져있슴니다
0
45
1
Reticle이 안나옵니다.
0
28
2
진행 방법 질문드립니다!
0
82
2
Singleton 관련 질문입니다.
1
54
2
안녕하세요. 계속 프로젝트를 해야지 하다가 결제하고 환경 설정 중입니다.
0
22
1
Export template 안됨
1
45
2
2-I) 왜 이 문제가 그래프이론 카테고리에 있는지 잘 모르겠습니다.
0
64
2
AddGameFrameworkComponentReceiver vs AddExtensionHandler
0
35
1
scanf("%d\n") 의미
0
28
1
필기자료 사라졌나요?(실기 일주일만에 안돼서 재도전-_-)
0
50
2
2주차 개념#12 트리 순회
0
33
2
백준 사이트 서비스 종료
0
147
3
26년 1회 실기 해설 강의
0
68
2





