문제 상황
언리얼에서 지뢰 아이템(AMineItem)을 구현하던 중, 일정 시간이 지난 뒤 폭발하도록 FTimerManager를 사용했다.
게임 실행 중 다음과 같은 크래시가 발생했다.
EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff
콜스택을 확인해보니 FTimerManager::Tick()에서 호출된 람다 함수 내부에서 문제가 발생했다.
원인 분석
문제의 핵심은 타이머 + 람다식 + UObject 수명 관리였다.
GetWorld()->GetTimerManager().SetTimer(
DestroyParticleTimerHandle,
[Particle]()
{
Particle->DestroyComponent();
},
2.0f,
false );
- 람다식이 UParticleSystemComponent* 포인터를 직접 캡처하고 있음
- 타이머는 2초 뒤 실행됨
- 그 사이에
- 액터가 Destroy() 됨
- 월드 정리 또는 GC 발생 가능
- 이미 파괴된 UObject에 접근하면서 Access Violation 발생
람다식은 UObject의 생명주기를 인식하지 못하기 때문에, 이미 해제된 메모리를 접근할 위험이 있다.
해결 방법 – TWeakObjectPtr 사용
람다식에서 UObject를 직접 잡지 않고, TWeakObjectPtr로 감싸 유효성 체크를 추가했다.
if (Particle)
{
TWeakObjectPtr<UParticleSystemComponent> WeakParticle = Particle;
FTimerHandle DestroyParticleTimerHandle;
GetWorld()->GetTimerManager().SetTimer(
DestroyParticleTimerHandle,
[WeakParticle]()
{
if (WeakParticle.IsValid())
{
WeakParticle->DestroyComponent();
}
},
2.0f,
false
);
}
- GC로 객체가 제거되면 IsValid()가 false
- 이미 파괴된 UObject 접근 방지
- 크래시 발생하지 않음
'내배캠 TIL' 카테고리의 다른 글
| [내배캠 TIL 260209] Unity 모델 에셋의 Unreal Engine 이식 및 좌표계 트러블슈팅 (0) | 2026.02.09 |
|---|---|
| [내배캠 TIL 260205] Unreal Enhanced Input 헤더 인식 이슈 (0) | 2026.02.05 |
| [내배캠 TIL 260130] Unreal TA PBR 텍스처 요소 정리 (0) | 2026.01.30 |
| [내배캠 TIL 260129] Unreal Cast는 무엇이고 왜 필요한가 (0) | 2026.01.29 |
| [내배캠 TIL 260123] Unreal Engine Collision 정리 (0) | 2026.01.23 |