C++ 잘못된 메모리 참조에 대한 유효성 검사
2021. 11. 16. 11:23ㆍ개발/C++
iocp를 다루는 중 자꾸 댕글링포인터가 발생해서 서버가 죽는 현상이 나타났다.
해당 포인터를 다른 사람이 만들었다는 것이 문제다.
내가 제어할 수가 없는 상황이라서 난감한 상황
포인터가 잘못된 메모리를 가르키면 어떻게 해야할까?
//main
#include <iostream>
#include "Ptr.h"
int main()
{
std::cout << "Hello World!\n";
Ptr* ptr = (Ptr*)malloc(sizeof(Ptr));
ptr->SetStr("qwer");
printf("%s\n",ptr->GetStr());
free(ptr);
printf("%s\n",ptr->GetStr());
}
//Ptr.h
#include <corecrt_memory.h>
class Ptr
{
public:
Ptr();
~Ptr();
private:
char str[32] = "adcd";
public:
void SetStr(const char* param) { memset(str, 0, 32); memcpy(str, param, 32); }
char* GetStr() { return str; }
};
//결과
Hello World!
qwer
硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼;
보다시피 쓰레기값이 들어가게 된다.
유효성 검사를 하려면 어떻게 해야할까?
기본적으로 포인터에 NULL처리를 미리 해줘서 판단하면 된다.
//main
#include <iostream>
#include "Ptr.h"
int main()
{
std::cout << "Hello World!\n";
Ptr* ptr = (Ptr*)malloc(sizeof(Ptr));
ptr->SetStr("qwer");
printf("%s\n",ptr->GetStr());
free(ptr);
ptr = NULL;
if(ptr != NULL)
printf("%s\n",ptr->GetStr());
}
//Ptr.h
#include <corecrt_memory.h>
class Ptr
{
public:
Ptr();
~Ptr();
private:
char str[32] = "adcd";
public:
void SetStr(const char* param) { memset(str, 0, 32); memcpy(str, param, 32); }
char* GetStr() { return str; }
};
//결과
Hello World!
qwer
이런것들이 잘되어있으면 상관없지만...
문제는 NULL처리가 안되어있는 댕글링 포인터가 날아온다는 것이다.
여러 방법을 생각하던 중..
고심끝에 금단의 방법을 사용했다.
//main
#include <iostream>
#include "Ptr.h"
int main()
{
std::cout << "Hello World!\n";
Ptr* ptr = (Ptr*)malloc(sizeof(Ptr));
ptr->SetStr("qwer");
printf("%s\n",ptr->GetStr());
free(ptr);
if(ptr->IsAlive())
printf("%s\n",ptr->GetStr());
}
//Ptr.h
#include <corecrt_memory.h>
#define CHECK_ALIVE 0x0F0F0F0F
class Ptr
{
public:
Ptr();
~Ptr();
private:
char str[32] = "adcd";
unsigned long isAlive;
public:
void SetStr(const char* param) { memset(str, 0, 32); memcpy(str, param, 32); isAlive = CHECK_ALIVE;}
char* GetStr() { return str; }
bool IsAlive() { return isAlive == CHECK_ALIVE; }
};
그냥 클래스를 초기화할때 아예 유효성키를 박아서 살아있는지 확인하는 방법이다.
실제로는 iocp에서 형변환등 여러 복잡한 과정이 있지만, 회사코드를 쓸수는 없으니 그냥 개념만 간단하게 해봤다.