2009-06-15 2 views
1

함수를 통해 데이터를 할당하는 방법을 알고, 함수가 반환 된 후에도 데이터가 할당됩니다. 이것은 기본 유형 (int, char **) 및 사용자 정의 유형 모두에 대한 것입니다. 다음은 두 가지 코드 스 니펫입니다. 할당이 반환 된 후에도 둘 다 함수 내에 할당됩니다.함수 (ANSI C)를 통해 데이터 할당

int* nCheck = NULL; 
int nCount = 4; 

CallIntAllocation(nCheck, nCount); 

nCheck[1] = 3; // Not allocated! 
... 

CallIntAllocation(int* nCheck, int nCount) 
{ 

    nCheck = (int*)malloc(nCount* sizeof(int)); 
    for (int j = 0; j < nCount; j++) 
     nCheck[j] = 0; 
} 

이전에 대한 동일한 동작하지만 사용자 정의 유형 :

typedef struct criteriatype 
{ 
    char szCriterio[256]; 
    char szCriterioSpecific[256]; 
} _CriteriaType; 

typedef struct criteria 
{ 
    int nCount; 
    char szType[128]; 
    _CriteriaType* CriteriaType; 
} _Criteria; 

... 
_Criteria* Criteria; 
AllocateCriteria(nTypes, nCriteria, Criteria); 
... 

void AllocateCriteria(int nTypes, int nCriteria[], _Criteria* Criteria) 
{ 
    int i = 0; 
    int j = 0; 

    Criteria = (_Criteria*)malloc(nTypes * sizeof(_Criteria)); 

    for (i = 0; i < nTypes; i ++) 
    { 
     // initalise FIRST the whole structure 
     // OTHERWISE the allocation is gone 
     memset(&Criteria[i],'\0',sizeof(_Criteria)); 

     // allocate CriteriaType 
     Criteria[i].CriteriaType = (_CriteriaType*)malloc(nCriteria[i] * sizeof(_CriteriaType)); 

     // initalise them 
     for (j = 0; j < nCriteria[i]; j ++) 
      memset(&Criteria[i].CriteriaType[j],'\0',sizeof(_CriteriaType)); 


    } 

} 

어떤 아이디어? 포인터를 참조로 전달해야한다고 생각하지만 어떻게 할 수 있습니까? 사전에

감사합니다, 선 스크린 복귀를 사용하여

답변

2

작동하지 않는 이유는 C의 함수 인수가 복사되기 때문입니다. 따라서 nCheck = NULL을 외부 컨텍스트에서 CallIntAllocation 함수로 전달하면 복사본이 만들어집니다. CallIntAllocation은 로컬의 nCheck 복사본을 malloc 호출의 반환으로 정의합니다. 그러나 바깥 쪽 복사본은 업데이트되지 않습니다. 여전히 NULL을 가리 킵니다.

가장 간단한 해결책은 새 포인터 값을 반환하고 이미 여러 사람이 제안한대로 할당하는 것입니다.

데이터 구조를 수정해야하는 함수가있는 경우 함수가 포인터가 가리키는 부분을 수정할 수 있도록 함수의 복사본이 아닌 포인터를 전달해야합니다. 수정하려는 데이터 구조 자체가 포인터이긴하지만 동일한 원칙이 적용됩니다.

그래서 다른 솔루션은 수정할 수 것 포인터 - 투 - 어 - 포인터를 취할 CallIntAllocation이 될 것입니다 경우, 또한 그 역 참조 포인터 포인트 :

CallIntAllocation(int** nCheck, int nCount) 
{ 

    *nCheck = (int*)malloc(nCount* sizeof(int)); 
    for (int j = 0; j < nCount; j++) 
     (*nCheck)[j] = 0; 
} 

및 호출을

CallIntAllocation(&nCheck, nCount); 

분명히이 상황에서 새 포인터 값을 반환하는 것은 현명한 접근입니다.

최종 점 : 당신이 가지고있는 경우에 사용할 수, "memset 함수"(C90가 아니라 C89은 AFAIK 그러나 단일 유닉스 규격의 일부) 루프

memset(ncheck, 0, nCount); 

을 "은"당신 대신 사용할 수 있습니다 (이것은 함수의 버전을위한 것이지 int ** 인자를 취하는 것이 아닙니다)

+0

감사합니다. 감사합니다. jmtd. 그리고 내가 다시 구조체를 초기화 할 수 있다고 생각합니다 memset : \t memset (& Criteria, 0x00, sizeof (Criteria)); – Sunscreen

5

?

Criteria * 
newCriteria() { 
    Criteria *criteria = malloc(..); 
    ... 
    return criteria; 
} 

/* the caller */ 
Criteria *c1 = newCriteria(); 
Criteria *c2 = newCriteria(); 

편집

발신자는 할당 된 메모리에 무료()

+1

완벽을 기하기 위해 발신자에게있는 무료()에 대한 몇 마디 말을 할 수 있습니다. – dmckee

+0

예 이런 식으로 사용하고 일했습니다. 감사합니다 – Sunscreen

0

당신이 할 수있는 "수익"포인터를 호출 할 책임이있다. NULL이 리턴되면 할당이 성공하지 못했음을의 L합니다.

4

당신은이 개 가능한 솔루션이 있습니다

int *CallIntAllocation(int nCount) 
{ 

    int *nCheck = (int*)malloc(nCount* sizeof(int)); 
    for (int j = 0; j < nCount; j++) 
     nCheck[j] = 0; 

    return nCheck; 
} 

int* nCheck = NULL; 
int nCount = 4; 

nCheck = CallIntAllocation(nCount); 

또는 ALLOC하려는 경우 * int로 포인터를 전달해야하는 배열 :

void CallIntAllocation(int **nCheck, int nCount) 
{ 

    *nCheck = (int*)malloc(nCount* sizeof(int)); 
    for (int j = 0; j < nCount; j++) 
     *nCheck[j] = 0; 
} 

int* nCheck = NULL; 
int nCount = 4; 

CallIntAllocation(&nCheck, nCount); 
+0

내 입력 할 때 귀하의 대답은 거기에 없었다 :/ – Pod

+0

고마워, 나는 반환 옵션을 사용했습니다. – Sunscreen

3

직접 귀하의 질문에 대답하려면 :

int* nCheck = NULL; 
int nCount = 4; 

CallIntAllocation(&nCheck, nCount); 

nCheck[1] = 3; // allocated! 
... 

void CallIntAllocation(int** pnCheck, int nCount) 
{ 
    int* nCheck = NULL; 
    nCheck = (int*) malloc(nCount * sizeof(*nCheck)); 
    for (int j = 0; j < nCount; j++) 
     nCheck[j] = 0; 
    *pnCheck = nCheck; 
} 

대신에 다음과 같이 제안합니다.

nCheck = CallIntAllocation(nCount); 

nCheck[1] = 3; // allocated! 
... 
int *CallIntAllocation(int nCount) 
{ 
    int * nCheck 
    nCheck = (int*) malloc(nCount * sizeof(*nCheck)); 
    for (int j = 0; j < nCount; j++) 
     nCheck[j] = 0; 
    return nCheck; 
} 
+0

감사합니다. 포드,이 방법으로 (int * 및 _Criteria를 각각 반환했습니다.) 작동합니다. – Sunscreen

관련 문제