int** copyArr;
copyArr = new int*[3];
for (int i = 0; i < 3; i++) {
copyArr[i] = new int(i);
}
for (int i = 0; i < 3; i++) {
delete[] copyArr[i];
}
delete[] copyArr;
=======================================================
Packet** copyArr;
copyArr = new Packet*[3];
for (int i = 0; i < 3; i++) {
copyArr[i] = new Packet("test");
}
for (int i = 0; i < 3; i++) {
delete[] copyArr[i];
}
delete[] copyArr;
타입만 다르고 나머지는 똑같은데
int 타입은 정상적으로 해제가 되고
Packet 타입은 빨간색 부분에서 런타임 에러가 발생하는데
상정할 수 있는 상황이 뭐가 있을까.
Packet 타입이 뭔지도 안 알려주는데 어떻게 아냐~! 라고 할 수 있겠지만
(내가 달아줄 수 있는 건 깃헙 링크밖에 없다...) https://github.com/inet-framework/inet/blob/master/src/inet/common/packet/Packet.cc
혹시 생각나는 거 있는 사람 있냐?ㅠㅠ
별 도움은 안될 거 같지만 나는 지금 omnet++ 이라는 네트워크 시뮬레이터에서 사용하는 inet 프레임워크를 이용해서 개발 중이야ㅠㅠ
아나나스피자
배열도 아닌데 delete[] 하니까 그렇지. 그리고 단순히 배열 기능을 이용할거면 그냥 vector 써라. C++에서는 raw 포인터 쓰는건 지양하는게 좋음.
모쏠탈출
Packet** copyArr;
copyArr = new Packet*[3];
이렇게 했는데도 배열로 취급 안되는 건감?? 값은 잘 들어가는데 나중에 해제할 때만 문제가 일어나서ㅠㅠ.. delete[] 말고 delete를 쓰면 이상하게도 copyArr의 요소 딱 하나만 해제되고 다른 요소들은 해제가 안되더라ㅠ
c++ 잘 몰라서 하나만 더 질문할께.. 처음에 array를 써서 array<Packet*, N> 이런 식으로 선언해서 쓰려고 했는데 결국엔 이것도 나중에 해제가 안되더라고ㅠㅠ Packet 말고 Packet*을 쓰는 이유는, 동적할당된 Packet 변수를 복제해서 보관하려고 하는데 제공하는 복제 메소드가
void dup() { return new Packet(*this) }
이런 식으로 사용되면서 결국에 나중에 해제가 필요해서 저런 식으로 사용했었거덩.
내가 뭔가 착각하는걸까?ㅠㅠ 질타 부탁드립니다...
Norton
모쏠탈출
위에도 적었듯이 그렇게 써도 디버깅할때 확인해보면 요소 하나만 해제되고 다른건 해제가 안되드라... 내가 잘못본걸 수도 있고
Norton
모쏠탈출
그건 아니야ㅠ 너희들 설명한 거 충분히 알았고 내가 잘못 생각했던 것도 알았어. 그런데 애초에 delete[]를 쓰게 된 계기가 delete를 했을 때 값이 제대로 해제가 안되서 썼었던 거야. 그냥 간단한 데모 코드 만들어서 테스트 해봐도 해제가 안되고 있어서 나도 답답하다 진짜ㅠ
JaGoon
array 클레스 보셈
모쏠탈출
std::array 얘 쓰라는 말이야??
JaGoon
요즘은 전부 스마트 포인터를 사용하기 때문에
c++도 생성 삭제 생각 안해도 됨
숨은음은
잠깐만... 이중포인터를 쓰는데
왜 int** a = new int*[3];
하고
a[i] = new int[3];
이런식으로 배열 선언을 안하냐?;;
이중 포인터면 배열이 2개여야 하는데 왜 혼자 배열 1개씀>?
저거 a[i]가 배열 선언이 안된건데 그냥 해제시 넘어간 것 뿐이지, 실제로는 오류나는 케이스인거임.
고대로 gcc 컴파일러로 해봐라 에러 뜨지 ㅇㅇ;
모쏠탈출
슬프게도 g++로 컴파일한거야ㅠㅠ
숨은음은
그래? 그럼.. 그냥 봐주는거임. 원칙적으로는 저딴 식으로 이중포인터 배열 선언하면 안됨
int ** a = new int*[3];
for(int i = 0; i < 3; i++)
{
a[i] = new int[10];
}
뭐 이런 식으로 해줘야지.
a[i]자체가 주소값을 갖는 포인터 변수인데 왜 배열 선언을 안 하고 그냥 int 선언을 해버림?
그럼 뭐하러 이중포인터 선언을 하냐.. 그냥 단일포인터 선언하면 되는데.
모쏠탈출
그러면 처음으로 돌아가서 delete[] 가 아니라 delete를 쓰면 해제되야 할 텐데 왜 제대로 해제가 안될까ㅋㅋ... 너무 화가 난드아ㅠ
숨은음은
일단 vscode로는 delete[] 붙이면 에러나서 터지고, delete 붙이면 아무 문제 없다.
int는 vscode의 경우 a[i] = new int(); 하고 delete[] a[i];를 하든 delete a[i]를 하든 자체 수정이 되서 에러는 안나지만,
Packet 클래스를 만들어서 delete[] packetArr[i]; 하면 터지고 delete packetArr[i]; 하면 문제 없음.
모쏠탈출
일단 내가 사용하는 시뮬레이터는 이클립스 기반 IDE를 사용하는데 delete[] 하면 터지고 delete 하면 동작이 되는데,
실제로 디버깅을 진행해보면 값이 해제가 안되더라구... delete를 했는데도 접근이 가능해부러...
Norton
모쏠탈출
아냐 안바꼈어ㅠㅠ 내가 뭔가 중대한 실수를 했거나 이 망할 시뮬레이터가 병신인거야ㅠㅠ 오늘은 밤샘 디버깅 각이다
숨은음은
int ** a = new int[3];
for(int i = 0; i < 3; i++)
{
a[i] = new int(1);
}
for(int i = 0; i < 3; i++)
{
delete a[i];
printf("%d", *a[i]);
}
delete[] a;
이렇게 해도 a[i]의 값은 쓰레기값이지만 출력 됨.
원천적인 a 자체를 delete 하기 전에는 값 접근은 쓰레기값일 지언정 접근은 된다.
모쏠탈출
근데 내 문제와 별개긴 한데 a[i] = new int(1); 에 왜 쓰레기값이 들어가? a[i]의 타입은 int* 이고 int*에 그냥 할당한 것 뿐인디?? 그냥 일반 int 변수 동적할당 하는 거랑 똑같은 거 아니야..?
숨은음은
아이.. 코드 똑바로 안 볼래.. 해제하고 출력했잖아.
모쏠탈출
아 너가 위에서 "a[i]자체가 주소값을 갖는 포인터 변수인데 왜 배열 선언을 안 하고 그냥 int 선언을 해버림?" 이렇게 말한 거만 생각하고 있어가지구 쏘리. 지금 정신이 없어가지고ㅠ 결국 저것도 delete[]를 왜 쓰냐에 대한 거였는데.. 진짜 정신이 없다. 늦은 밤까지 댓글달아줘서 고맙다... 복받을꺼야
숨은음은
그래서 delete[] a 하기 전에는 일단 a가 int*의 3칸 어치는 무조건 할당되야 하잖아.
우리는 a[i]의 메모리 할당을 없앤 거지 a 자체를 할당 삭제를 한게 아니니까.
하위 a[i]를 해제했다고 a가 가지고 있는 int* 3칸 어치가 해제되버리면 큰일이지 않겠음?
그래서 a[i]는 해제되었으므로 a가 가지고 있는 int* 3칸 어치에는 쓰레기값만 남게되는 거야.
참고로 delete[] 는 배열로 선언 되었을 경우에 할당 삭제하는거지, 배열로 선언되지 않은 포인터 변수는 그냥 delete 해야함.
대표적으로 클래스 변수들을 보통은 주소값으로 선언하는데(데이터 직접접근을 위해)
Packet* temp = new Packet();
이렇게 말이지.
이거 해제할 때 delete[] temp하면 안돼. 저거는 그냥 포인터 변수인거지 배열의 첫번째 위치를 나타내는 배열 포인터 변수가 아니니까.
이럴 경우에는 delete temp해야해.
만약 네가
Packet* temp = new Packet[3];
이런 식으로 선언했다면 temp는 더 이상 단순 포인터 변수가 아니라 배열 포인터 변수가 됬잖아
그래서 temp를 해제하려면
delete[] temp 해야함.