开发者

How to get size of different kinds of types in the same function using C?

开发者 https://www.devze.com 2023-02-02 17:00 出处:网络
I\'m writing a function which increases the size of a dynamic memory object created with malloc. The function should as arguments take a pointer to the memory block to be increased, the current size o

I'm writing a function which increases the size of a dynamic memory object created with malloc. The function should as arguments take a pointer to the memory block to be increased, the current size of the block and the amount the block is 开发者_StackOverflow中文版going to be increased.

Something like this:

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;
}

The problem is that I want the function to work no matter what pnt points to. How do I achieve that?


This type of function cannot possibly work, because pnt is local and the new pointer is lost as soon as the function returns. You could take an argument of type xxxxxx ** so that you could update the pointer, but then you're stuck with only supporting a single type.

The real problem is that you're writing an unnecessary and harmful wrapper for realloc. Simply use realloc directly as it was meant to be used. There is no way to make it simpler or more efficient by wrapping it; it's already as simple as possible.


You pass in the size as an argument. You can use a convenience macro to make it look the same as your function:

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

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

Edit to show that your convenience macro would also need to add call-by-reference semantics.


Pass in the element size as a separate parameter:

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
}

It's the most straightforward solution, if not the most elegant. C just doesn't lend itself to dynamic type information.

Edit

Changed the type of pnt in response to Steve's comment.

As caf points out, this won't work, even with the "fix" per Steve. R.'s right; don't do this.

0

精彩评论

暂无评论...
验证码 换一张
取 消