malloc으로 할당하고 다시 new로 할당했을 때 해제는 어떤 방식으로 해야 하나요?
글쓴이: dltkddyd / 작성시간: 금, 2014/05/02 - 2:47오후
#include <cstdlib> class Test { public: char* chs; Test() {chs=NULL;} Test(const char* _chs) { chs=new char[1]; *chs=*_chs; } Test& operator(const Test& src) { chs=new char[1]; *chs=*src.chs; } ~Test() { if(chs!=NULL) { delete[] chs; chs=NULL; } } }; int main() { Test* pt1=malloc(sizeof(Test)*10); new(pt1) Test[10]; const char* alpha="A"; Test obj1(alpha); for(unsigned long int i=0;i<10;i++) { pt1[i]=obj1; (*obj1.chs)++; } for(unsigned long int i=0;i<10;i++) { pt1[i].~Test(); } delete pt1;//바로 이 for문과 delete문이 pt1의 메모리 전부를 깨버린다고 생각합니다. free(pt1);//그런데 이것을 또 언급해주어야 하나요? //제가 또 만든 다른 코드에서는 ~Test와 delete만으로는 오류가 발생하는 것을 확인했습니다. 프로그램 종료 직전에요. //왜 이런 문제가 발생하나요? return 0; }
언급한 코드 말고 유사한 다른 코드에서 이런 오류 메시지가 출력됐습니다.
Error in './test18':free():invalid next size(fast):0x0000000001275110
======= Backtrace: =======
~~~~~
Forums:
앞의 질문들도 그렇고, 뭘 하려고 하시는지
앞의 질문들도 그렇고, 뭘 하려고 하시는지 모르겠습니다.
코드가 어디어디가 잘못된 건지 말씀드리는거야 어렵지 않습니다만 의도를 알아야 답변을 더 드릴 수 있지 않을까요?
기반타입의 메모리를 깨는 문제에 대해 질문드린 건데요.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
문제가 생길 여지가 많습니다. ABI를 살펴보아야할
문제가 생길 여지가 많습니다. ABI를 살펴보아야할 것 같습니다만 new T[N] 형태는 해제 시 delete [] T 로 해제하는데, 이 때 소멸자를 올바르게 호출하기 위해 할당받은 메모리의 어딘가에 N을 저장해둡니다. pod type에 대해선 소멸자를 호출할 필요가 없으므로 컴파일러가 이를 저장하지 않을 수도 있지만, 저장을 하든 하지 않든 C++표준에서 정의된 부분이 아니므로 저런 코드는 사용하지 않는 것이 좋습니다.
밑에 답글에서도 반복적으로 달린 C++에서 사용하는 방법을 사용하라는 답변을 드릴 수 밖에 없을 것 같습니다.
굳이 메모리 할당을 malloc으로 하고 싶으시다면 저런 직접적인 방법보다는 ::operator new(size_t)를 정의하시는 편이 낫습니다.
이것 저것 시도해 보는 것은 좋다고
이것 저것 시도해 보는 것은 좋다고 생각합니다.
확실히 알고 싶다면 malloc과 new의 소스 코드를 한번 연구해 보세요.
delete pt1을 왜 해주는지요?
pt1은 malloc으로 할당받은 메모리입니다. 따라서 free로 해제해 주어야 합니다.
new(pt1)은 그저 생성자 함수 자체를 수동으로 호출해줄 뿐이고 메모리에 관해서는 아무 것도 하지 않습니다.
pt1[i].~Test(); 이것도 소멸자 함수만 수동으로 호출해줄 뿐 메모리에 관해서는 아무 것도 하지 않습니다.
따라서 delete pt1은 애초에 해줄 필요가 없는 것이며, 오히려 new로 할당받지 않은 메모리를 해제하려 하므로 문제의 소지가 됩니다. 특히 해당 포인터 타입에 소멸자가 별도로 있는 경우에는 더욱 그렇습니다.
앞의 질문에서도 그렇고 해당 문법을 오해하고 계신 것 같은 느낌입니다.
malloc는 free와, new는 delete와, 수동 생성자호출은 수동 소멸자호출과 짝을 이뤄주시면 아무런 문제가 없습니다. 여기서 발생한 포인터들을 제대로 짝지어주지 않고 서로 섞어 사용하니까 문제가 계속 발생하는 것입니다.
--
댓글 달기