2016-06-14 2 views
0

나는 C 프로그래밍의 기본을 배우고 있으며, 매우 이상하고 어렵다고 생각한다. 특히 동적 메모리 할당, 포인터 및 이와 유사한 것들. 나는이 기능을 처음 접했을 때 무엇이 ​​잘못되었는지 이해하지 못했다.함수에서 malloc을 사용하는 경우는 언제입니까?

char *strdup(const char *p) 
    { 
     char *q; 
     strcpy(q, p); 
     return q; 
    } 

저는 malloc과 무료 q가 있어야한다고 생각합니다. 그러나 함수 "return q". 그것이 자신의 기억에 q 값을 저장할 것이라는 것을 의미하지는 않습니다. 따라서 함수가 실행 된 후에도 데이터가 저장됩니까?

malloc을 사용하는 것이 적절한 경우? 지금까지 내가 알기로는 함수에서 선언 된 변수가 필요할 때마다 새로운 변수를 malloc해야한다. 그게 사실이야? malloc이 필요한 다른 상황이 있습니까?

+0

을 strcpy''에 대한 호출을보고 : 예를 들어,에서는 StrDup은 또한 다음과 같은 방법으로 재 작성 할 수 있습니다. 'p'가 가리키는 문자열을'q'가 가리키는 배열로 복사하려고합니다. 'q'는 배열을 가리 키도록 초기화되지 않았습니다. 여기에는 가비지 값이 포함되어 있으므로이 값을 호출하면 메모리가 손상됩니다. 먼저 'q'를 'malloc'이 반환하는 것과 같은 적절한 저장소 블록의 주소로 설정해야합니다. 그래야만 그 목표에 쓸 수 있습니다. 단순한. –

+0

q는 주소이지만 초기화되지 않았습니다. strcpy는 데이터를 취하여 q가 가리키는 위치에 넣으려고하지만 q는 유효하지 않은 것을 가리 킵니다. malloc을 호출하고 결과를 q에 대입하면 q가 데이터를 저장할 수있는 위치가됩니다. –

+0

* 실제 * 문제는 수명에 대해 알아야한다는 것입니다. 유감스럽게도 대부분의 자습서에서는 중요한 과목이 아닌 구문 만 가르칩니다. – o11c

답변

4

내 개인적인 규칙은 다음과 같습니다 : malloc() 개체가 너무 커서 스택에 넣을 수 없거나 현재 블록의 범위 밖에 존재해야하는 경우 사용하십시오. 귀하의 경우, 저는 믿습니다, 당신은 다음과 같은 것을 수행해야합니다

char *strdup(const char *p) 
{ 
    char *q; 
    q = malloc(strlen(p) + 1); 
    if(NULL != q) 
     strcpy(q, p); 
    return q; 
} 
5

질문의 유형은 포인터, 그리고 포인터는 주소를 보유 - 그래서 당신이 반환하는 것은 포인터가 보유하고있는 주소입니다.

포인터에 올바른 주소를 지정할 때까지 포인터는 누가 알고 있는지, 어디서나 소유 할 수도 있고 가지지 않을 수도 있으며 액세스 할 수있는 권한이 있습니다. 따라서 strdup 호출은 p에 저장된 주소의 문자열을 사용자가 소유하지 않은 위치로 복사합니다.

malloc을 먼저 수행하고 q를 malloc의 결과로 주면 q가 유효한 주소를 갖게되고 strdup이 복사본을 메모리에 저장합니다 (malloc'd 충분한 공간이 있다고 가정 할 때). 문자열의 경우 - p의 strlen은 필요한만큼 알려줍니다.)

그런 다음 q를 반환하면 발신자에게 주소도 제공하게됩니다. 해당 주소의 모든 코드는 사용자가 입력 한 문자열을 볼 수 있습니다. 미래의 코드가 그 주소를 해방시키는 것이라면, 그 주소는 공중에 올라와 있습니다.

그렇다면 보유하고있는 주소를 반환하기 전에 q를 해제하고 싶지 않습니다. 발신자가 준비가되었을 때 발신자가 보낸 주소를 무료로 보내야합니다.

malloc의 경우, 함수가 완료된 후에도 실행 가능할 주소를 반환하려면 malloc해야합니다. 호출자에게 로컬 변수의 주소를 지정합니다 (예 : 나쁜 것 : 함수가 반환 될 때 메모리가 해제되고 더 이상 소유하지 않습니다.

malloc의 또 다른 전형적인 사용법은 나무와 목록과 같은 동적 데이터 구조를 구축하는 것입니다. 앞에서 필요한 메모리 양을 알 수 없으므로 필요한만큼 목록이나 트리를 작성해야합니다. malloc ' 구조의 각 노드에 대해 더 많은 메모리를 할당해야합니다.

0

malloc(X)은 힙에 재생할 공간 (크기는 X 바이트)을 만듭니다. 이 X 바이트에 쓰는 데이터는 함수가 반환 할 때 그대로 유지되므로 결과적으로 strdup() 함수가 힙의 해당 공간에 쓴 내용을 읽을 수 있습니다.

free()은 힙의 공간을 확보하는 데 사용됩니다. malloc() 또는 realloc() 호출의 결과로만 얻은이 함수에 대한 포인터를 전달할 수 있습니다.이 함수는 일 수 있습니다.은 데이터를 지우지 않습니다. 이는 방금 malloc()으로 전화하면이 방금 해방 한 것과 동일한 공간의 주소를 반환한다는 것을 의미합니다. 나는 "may"라고 말하고 있습니다. 왜냐하면 이것들은 모두 정의 된 구현이며 의존해서는 안되기 때문입니다. qp에서 하나 당신이 쓴 코드의 조각에서

strcpy() 기능 복사 바이트 하나는 위치 q (후 복사뿐만 아니라 \0)가 가리키는에서 \0을 찾을 때까지. 데이터를 어딘가에 쓰려면 먼저 쓸 데이터에 공간을 할당해야합니다. 따라서 하나의 옵션으로 malloc()을 호출하여 공간을 생성 한 다음 거기에 데이터를 쓸 수 있습니다. 당신의 OS는 한 프로그램이 당신이 필요보다 더 많은 공간을 ocupying 할 수있다 실행으로 끝 하지만를 프로그램 할 때 malloc()에 의해 할당 된 공간을 회수하므로

음, free() 호출하면 의무적으로하지 않습니다 - 그것은 나쁜 프로그램을 위해, 다른 프로그램을 위해, OS와 우주 전체를 위해.

0

저는 malloc과 무료 q가 있어야한다고 생각합니다. 그러나 함수 "return q". 그것이 자신의 기억에 q 값을 저장할 것이라는 것을 의미하지는 않습니다. 따라서 함수가 실행 된 후에도 데이터가 저장됩니까?

아니요, 데이터가 저장되지 않습니다. 사실 포인터 q를 할당하지 않고 포인터 q를 사용하면 문제가 발생할 수 있습니다. 또한이 함수의 실행이 완료되면 변수 char * q가 파기됩니다.

@ Michael의 대답에 의해 제안 된대로 데이터를 복사하기 전에 포인터 q에 메모리를 할당해야합니다.하지만이 함수로 데이터 반환을 완료하면 수동으로 할당 한 메모리를 해제해야합니다 (그렇지 않으면). 원인 메모리 누수

가 사용하기 적합한

char *strdup(const char *p) // From @Michael's answer 
{ 
    char *q; 
    q = malloc(strlen(p) + 1); 
    if(NULL != q) 
     strcpy(q, p); 
    return q; 
} 

void someFunction() 
{ 
    char* aDupString = strdup("Hello World!!!"); 
    /*... somecode use aDupString */ 
    free(aDupString); // If not freed, will cause memory leaks 
} 
를 (메모리 할당 있지만 포인터가 당신이 할당 된 메모리의 청크를 참조하지 않으며, 따라서 프로그램 실행에 걸쳐 액세스 할 수 없습니다가되는 상황) malloc? malloc이 필요한 다른 상황이 있습니까?

은 다음과 같은 경우에 사용하는 것이 적절하다 :

1

이> 배열의 사용 크기는 컴파일 타임에 알려져 있지 않다.

2> 크기 유연성이 필요합니다. 예를 들어, 함수는 작은 데이터 크기와 큰 데이터 크기로 작업해야합니다. (데이터 구조와 같은 같은 연결리스트, 스택, 큐, 등)

내가 지금까지 알고있는 것처럼 내가 새로운 변수를 내가 함수에 선언 된 변수가 될 것을 필요로 할 때마다 malloc을해야한다는 것입니다 다른 곳에 사용됩니다. 그게 사실이야?

나는 이것이 부분적으로 사실이라고 생각한다. 당신이 무엇을하려고하는지에 따라, malloc을 사용하여 주위를 돌아 다니는 방법이있을 수 있습니다.글쎄,

void strdup2(const char *p, char* strOut) 
{ 
    // malloc not require 
    strcpy(strOut, p); 
} 

void someFunction() 
{ 
    char aString[15] = "Hello World!!!"; 
    char aDupStr[sizeof(aString)]; 
    strdup2(aString, aDupStr); 

    // free() memory not required. but size is not dynamic. 
} 
관련 문제