포인터에는 몇 가지 어려움이 있습니다.
- 별칭 다른 이름 / 변수를 사용하여 개체의 값을 변경할 가능성.
- 비 지역성 (local-locality ) 선언 된 것과 다른 컨텍스트에서 객체 값을 변경할 가능성 (참조에 의해 전달 된 인수에서도 발생)
- 수명 불일치 포인터의 수명은 가리키는 객체의 수명과 다를 수 있으며 이는 잘못된 참조 (SEGFAULTS) 또는 가비지로 이어질 수 있습니다.
- 포인터 산술 . 일부 프로그래밍 언어는 포인터를 정수로 조작 할 수있게 해주므로 포인터가 어디든지 가리킬 수 있습니다 (버그가있을 때 가장 예상치 못한 위치 포함). 포인터 산술을 올바르게 사용하려면 프로그래머가 가리키는 객체의 메모리 크기를 알고 있어야하며, 더 생각해야합니다.
- 유형 캐스트 포인터를 한 유형에서 다른 유형으로 캐스트 하는 기능을 사용하면 의도 한 것과 다른 객체의 메모리를 덮어 쓸 수 있습니다.
그렇기 때문에 프로그래머는 포인터를 사용할 때 더 철저하게 생각해야합니다 ( 두 가지 추상화 수준에 대해서는 모르겠습니다 ). 이것은 초보자가 저지른 일반적인 실수의 예입니다.
Pair* make_pair(int a, int b)
{
Pair p;
p.a = a;
p.b = b;
return &p;
}
위와 같은 코드는 포인터 개념이 아닌 함수 프로그래밍 언어와 같은 이름 (참조), 객체 및 값 중 하나와 가비지 수집 기능이있는 언어 (Java, Python)가있는 언어에서 완벽하게 합리적입니다. .
재귀 함수의 어려움은 충분한 수학적 배경이없는 사람들 (재귀가 일반적이며 필요한 지식이있는 사람들)이 함수가 이전에 호출 된 횟수에 따라 다르게 동작한다고 생각할 때 발생합니다 . 재귀 함수 는 실제로 이해 하는 방식 으로 생각해야하는 방식으로 생성 될 수 있기 때문에이 문제는 더욱 악화 됩니다.
데이터 구조가 내부에서 수정되는 Red-Black Tree 의 절차 적 구현과 같이 포인터가 전달되는 재귀 함수를 생각하십시오 . 기능적인 상대 보다 생각하기가 더 어렵다 .
이 질문에는 언급되어 있지 않지만 초보자가 어려움을 겪는 다른 중요한 문제는 동시성 입니다.
다른 사람들이 언급했듯이 일부 프로그래밍 언어 구문에는 개념이 아닌 추가적인 문제가 있습니다. 이해하더라도 이러한 구문에 대한 단순하고 정직한 실수는 디버깅하기가 매우 어려울 수 있습니다.