약간의 생각을 한 후에 2 번째 예가 왜 충돌하지 않았는지 어느 정도 확실하게 말할 수 있습니다. 다음으로, 인수의 수 (int
)와, char **
와 인수와 char **
로서도 환경 문자열 main
를 호출하는 프로그램이 실행될 때
는 CRT (C 런타임) 스택 3 개 값을 푸시.
이제는 main
함수를 작성할 때 항상 처음 두 값을 읽고 함수의 인수 (있는 경우)를 전달합니다. 세 번째 인수를 포함하면 세 번째 값도 전달되고 그렇지 않으면 스택에 남아 있습니다. 그래서 프로그램의 시작 스택은 다음과 같습니다
첫 번째 예에서
+--------+
| # args |
+--------+
| args |
+--------+ <------ stack pointer
| envs |
+--------+
첫 번째 예에서 전체 스택처럼 보이는, 그래서 당신이 다음 포인터, 스택에 int
및 구조체를 할당 :
+--------+
| # args |
+--------+
| args |
+--------+ <------ stack pointer
| arg | <------ your integer, initialized in code
+--------+
| ob | <------ your struct, initialized in code
+--------+
| sample | <------ your pointer, uninitalized = garbage
+--------+
그래서 sample
순수한 쓰레기와이 프로그램을 충돌 역 참조하려고합니다.
+--------+
| # args |
+--------+
| args |
+--------+ <------ stack pointer
| sample | <------ pointer, uninitalized (!)
+--------+
포인터가 여전히 uninitalized되어 있지만 덮어 값 배열 실제 포인터이다 envp
이다 :
이제 두 번째 예에서, 스택은 다음과 같다 char **
.역 참조 할 때, "char to pointers"의 배열을 되 찾을 수 있으므로 안전하게 덮어 쓸 수 있습니다 (원래 포인터로 더 이상 취급하지 않는 한). 메모리가 할당되고 사용할 수 있습니다.
이제는 구현이 많이 달라졌지만 컴파일러에 맞을 것으로 보입니까? gdb
으로 덮어 쓰기 전에 (char**)sample
이 실제로 환경 변수 배열을 가리키고 있는지 확인할 수 있습니다.
the pointer in action http://img651.imageshack.us/img651/5918/69916340.png
는 당신이 좋은 C++ 책을 가지고 있습니까 : 32 비트 릴리스 모드에서 MSVC++ 10에서
스크린 샷 (디버그 모드는 모든 변수 강제 이런 종류의 물건을 방지하기 위해 초기화)? 그렇게한다면 상당한 깊이의 포인터와 그 사용법을 논의해야합니다. 그렇지 않다면 [The Definitive C++ Book Guide and List] (http://stackoverflow.com/questions/388242/)에 나와있는 소개 도서 중 하나를 얻는 것이 좋습니다. –
아니요, 아직 없습니다. 어려운 길을 배우는 것이 잘못된 이유는 무엇입니까? – user383352
@ drenami : 당신은 근본적으로 당신을 가르치기 좋은 책이없는 프로그램을 작성하면서 C++의 걸림돌을 실제로 배울 수 없습니다. –