C++ 클래스 인스턴스의 지역변수 초기화 오류 & C4996 에러
646
작성한 질문수 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;
}
4-O 채점 관련 질문
0
7
1
코딩살구클럽가입
0
12
1
코딩살구클럽 가입
0
25
2
업캐스팅 문제 예시 5
0
30
2
(기출) 2025년 2회 이론 파트
0
26
2
26년 1회실기
0
31
2
비쥬얼 스튜디오로 해도 되나요?
0
42
2
강의 자료
0
37
2
scanf_s 에 관해서 오류나옵니다.
0
40
3
27:15 break 출력
0
35
2
최신 엔비디아 CUDA 아키텍처에서의 결정적 변경 사항
0
26
1
자문자답- 맞는지 틀린지 확인부탁드립니다.
0
33
1
55강 파이썬에만있는 연산자들
0
37
2
55강의 파이썬에서만 있는 연산자들
0
29
2
[문의] 강의 코드 제공여부
0
37
2
코딩살구클럽 가입 문의
0
69
2
코딩 살구 클럽 컴파일 에러
0
46
3
추천 문제
0
41
2
코딩살구클럽 승인
0
47
2
이 강의를 다 들으면 어떤 강의를 들어야 하나요?
0
64
2
선생님 13.3을 써도 큰 차이가 없나요?
0
37
2
코살구 1주차 1940번 문제 조건과 프라이빗 테스트 불일치 문의
0
41
2
메모리 동적할당시 메모리창 빨간 글씨
0
37
2
문제를 고민하는 시간 관련
0
33
2





