2011-01-06 2 views
1

malloc으로 만든 동적 메모리 객체의 크기를 늘리는 함수를 작성하고 있습니다. 이 함수는 인수가 증가 할 메모리 블록에 대한 포인터, 블록의 현재 크기 및 블록 증가량을 가져야합니다. 이 같은C를 사용하여 같은 함수에서 여러 가지 유형의 크기를 얻는 방법은 무엇입니까?

뭔가 :

int getMoreSpace(void **pnt, int size, int add) { 
    xxxxxx *tmp; /* a pointer to the same as pnt */ 
    if (tmp = realloc(pnt, (size+add)*sizeof(xxxxxx))) { /* get size of what pnt points to */ 
     *pnt=tmp; 
     return 1; 
    else return 0; 
} 

문제는 그 기능에 상관없이 무엇을 PNT 포인트를 작동하지 할 것입니다. 어떻게해야합니까?

답변

9

pnt이 로컬이고 함수가 반환 되 자마자 새 포인터가 손실되기 때문에이 유형의 함수가 작동하지 않을 수 있습니다. 포인터를 업데이트 할 수 있도록 xxxxxx ** 형식의 인수를 사용할 수 있지만 단일 형식 만 지원할 수 있습니다.

실제 문제는 realloc에 대해 불필요하고 유해한 래퍼를 작성하고 있다는 것입니다. realloc을 사용하기 위해 그대로 사용하십시오. 래핑 (wrapping)하여 더 단순하거나 더 효율적으로 만들 수있는 방법이 없습니다. 그것은 이미 가능한 한 간단합니다.

+0

나는 당신이 말하는 것을 정말로 얻지 못합니다. pnt가 지역적으로 중요한 이유는 무엇입니까? 함수가 반환 될 때까지만 필요합니다. 또한이 래퍼가 왜 위험합니까? 다른 종류의 상황에서 내 프로그램에서이 종류의 크기 증가를 몇 번하고 있습니다.이 기능을 사용하면 훨씬 더 깨끗하고 단순 해집니다. 왜냐하면 동일한 시간에 많은 시간을 입력하지 않아도되기 때문입니다. 어쨌든 기능의?). – paldepind

+0

100 % 확신 할 수는 없지만 C에 '로컬'포인터가 없다고 생각합니다. –

+4

@Stefanos : 함수 인수는 함수가 반환 할 때 범위를 벗어나는 "로컬 변수"입니다. . 'ptr'에 새로운 값을 할당해도 효과가 없습니다; 실제로 컴파일러는 할당을 최적화 할 수 있고 최적화해야합니다. –

2

크기를 인수로 전달합니다. 당신은 당신의 기능과 동일하게 보이게하기 편리한 매크로를 사용할 수 있습니다

#define getMoreSpace(P, SZ, ADD) getMoreSpaceFunc(&(P), sizeof(*(P)), (SZ), (ADD)) 

int getMoreSpace(void **pnt, size_t elem_size, int size, int add) { 
    *pnt = ... 
} 

편집을 사용자의 편의를 매크로도 호출에 의해 참조 의미를 추가 할 필요가 있음을 표시합니다. 별도의 매개 변수로 요소 크기에

+0

매크로를 사용하는 이유는 무엇입니까? sizeof는 변수를 전달하는 것만으로 작동합니까? 나는 형식을 인수로 받아 들였을 뿐이지 만? – paldepind

+0

'sizeof'는 연산자입니다. 유형을 볼 수 있어야합니다. 매크로는 변수의 유형을 볼 수있는 원래 코드의 텍스트로 대체합니다. 당신의 함수 안에서 당신은 여전히 ​​타입 정보를 잃어 버리지 만 매크로는 당신을위한 크기로 전달됩니다. 더 나아가 (편집에서 설명한대로) 매크로를 사용하여 대상 포인터의 주소를 가져올 수 있습니다. –

+0

... 또한, 나는 당신이 *해야한다고 생각하지 않기 때문에 R의 답을 썼다. 그러나 나는 당신의 질문에 대한 기술적 인 답이 계몽적이라고 생각했다. –

1

패스 :

int getMoreSpace(void **pnt, int size, int add, size_t eltSize) 
{  
    void *tmp; 
    if (tmp = realloc(pnt, (size+add)*eltSize)) 
    { 
    *pnt=tmp; 
    return 1; 
    } 
    else 
    return 0; 
} 
... 

int *p = malloc(100 * sizeof *p); 
... 
if (!getMoreSpace(&p, 100, 20, sizeof *p)) 
{ 
    // panic 
} 

그것은 가장 간단한 해결책이 아니라면 가장 우아한이야. C는 동적 인 타입 정보를 제공하지 않습니다.

편집

스티브의 의견에 대한 응답으로 pnt의 유형을 변경.

caf가 지적했듯이 스티브 당 "수정 사항"이 있더라도이 기능은 작동하지 않습니다. R.의 권리; 이러지 마.

+0

이것은 포인터에 대한 포인터를 사용하지 않으면 작동하지 않는다.* p는 realloc에 ​​의해 반환 된 값으로 할당되지 않습니다. –

+0

@ 스티브 멜빈. 이봐. 나는 그것을 알고 있었다. 정말. 예제를 수정하여이를 수정합니다. 와우, 하루에 두 downvotes; 그것은 저를위한 기록입니다. –

+0

'void *'타입의 lvalue를 사용하여'int *'타입의 객체를 수정하는 것은 허용되지 않습니다 - 그러한 코드는 정의되지 않은 동작을합니다. – caf

관련 문제