2013-08-19 4 views
1

제목이 내 질문입니다. 메모리에서 인수는 초기화 방법에 따라 스택이나 힙에 위치 할 수 있지만 하드 코딩 된 정보는 어떻게 처리됩니까?"하드 코딩"과 메모리 관련 인수 전달의 차이점은 무엇입니까?

void function(){ 

    ifstream infile("home/some/file/path"); 

} 

void function(char* filePath){ 

    ifstream infile(filePath); //filePath points to a character array which contains home/some/file/path 

} 

어떤 메모리 연루의 사용으로 인해 발생할 수 : 예를 들어

는,이 사이의 차이점은 무엇 ifstream

의 생성자를 사용합니다 다른 하나 이상? (char *가 정확하게 free'd되지 않으면 다중 스레딩이 힙 손상을 초래할 수 있습니다.

나는 큰 문제에 대한 해답을 적용 할 수 있도록 차이점과 가능한 함축적 의미를 이해하기 위해 노력하고 있습니다. 내가 잘못된 진술/가정을했다면 모든 통찰력을 환영하고 언제든지 나를 바로 잡을 수 있습니다!

+2

'filePath'의 정의와 생성 방법에 따라 달라집니다. 그러나 힙 부패는'자유롭지 않은 '것에 기인하지 않는다. 힙 손상은 할당 된 버퍼 외부의 잘못된 코드 쓰기로 인해 발생합니다. –

+1

첫 번째 예에서 문자열은 프로세스의 읽기 전용 영역에 놓입니다. 따라서 거기에 피해를 줄 수있는 것은 없습니다. –

+0

@MatsPetersson 만약 내가 묻지 않았다면, 얼마나 많은 다른 방법으로'char * '를 정의 할 수 있을까요? 나는 당신이'char * foo = (char *) malloc (16)'과 같은 것을 할 수 있다는 것을 알고있다. 그러나 다른 것은, 대중적인 방법이 있다고 가정 해 보자. –

답변

2

리터럴 (첫 번째 예제에서 보여주는 것)은 실행 가능 파일의 정적 초기화 부분에 배치됩니다 (따라서 * Nix 시스템에있는 경우) strings 명령을 사용하여 응용 프로그램의 모든 리터럴. 당신이 함수에서 포인터를 수정하려고하지 않는 한

귀하의 두번째 예는 실제로

void function(const char* filePath) { ... } 

으로 수정해야합니다. 그 함수의 메모리는 어디에서든지 올 수 있습니다 (함수에 전달되는 문자열 리터럴, 응용 프로그램의 다른 곳에서 선언 된 상수 문자열, 메모리에 저장된 문자열 및 명령 줄 또는 콘솔에서 입력 한 문자열 등)

여기서 멀티 스레드로 실행할 주요 문제는 2 개 이상의 스레드가 동일한 파일을 동시에로드하려고 시도하는 경우입니다. 모두 읽는다면 문제가되지 않을 수도 있습니다. 그러나 쓰레드를 쓰고 싶은 파일이 있다면, 다른 쓰레드는 교착 상태가됩니다. 이 질문은 문자열 질문과 직접적인 관련이 없습니다.

+0

감사합니다. 아주 잘 설명되었습니다. 나는이 문제를 아직 풀지 않을 것이다. 왜냐하면 내가 더 논의하기를 원하기 때문이다. :) –

0

"하드 코드 된"또는 리터럴 값은 일반적으로 프로그램 지침의 일부입니다. 예를 들어

int i = 0; 

과 같은 값을 지정하면 아키텍처 수준에서 어셈블리 명령을 사용하여 값 0이로드됩니다. 그래서 내가 얻는 것은 그들이 컴파일러와 프로그램에 의해 처리되고 아마도 전혀 메모리를 사용하지 않거나 스택에있을 것입니다.

char *와 같은 값의 경우 먼저 메모리 할당을 처리하므로 문자열을 사용하는 것이 좋지만 큰 문자열은 힙에 저장되는 반면 작은 문자열 (7 자 미만)은 스택에 처리되도록 최적화되어야합니다 ("new"가 포함되지 않은 경우).

1

다른 사람들은 리터럴 문자열이 실행 파일의 일부 읽기 전용 메모리에 저장되어 있고 char 포인터가 해당 메모리를 직접 가리키고 있다는 것을 잘 알고 있습니다.

두 번째 옵션이 "좋음", "나쁨"또는 "위 없음"중 무엇이 높은지는 filePath의 출처에 따라 크게 달라집니다.일부 코드가 char *filename = new char [x]; strcpy(filename, "...");을하는 경우

분명히 한 다음 해당 delete [] filename;있을 필요 - 그리고 x 요구에 맞게 문자열 "..." 충분히 오래 할 수 있습니다.

이 경우에는 std::string을 사용하는 것이 더 안전합니다. 할당은 클래스에서 처리되고 소멸자에서 처리됩니다.

방정식에 스레드를 삽입하면 문자열 정의 위치도 걱정해야합니다. 인스턴스가 하나 뿐인 클래스에서 전역 변수 또는 스택에 있습니다. "스택"만 안전하고 제한 사항이 있습니다 :[또는 스레드가 만들어지기 전에 다른 함수]에서 에 대한 포인터를 스레드에 전달하면 메모리가 여러 번 할당 된 모든 종류의 "재미"를 가질 수 있습니다 하나의 문자열로, 다른 스레드에 의해 덮어 쓰여지는 데이터와 무엇이 있습니까? 물론 스레드가 데이터를 변경하지 않으면 전역 변수 나 스레드 외부의 스택에도 문제가 없습니다.

이것은 "문자열이 어떻게 생성되는지에 따라 달라집니다"라는 의미입니다. 세부 사항은 여기서 중요한 부분입니다.