如何使用C获得同一函数中不同类型的大小?
我正在编写一个函数,它增加了使用malloc创建的动态内存对象的大小。函数应该作为参数获取一个指针,指向要增加的内存块、块的当前大小以及块将要增加的量 大概是这样的:如何使用C获得同一函数中不同类型的大小?,c,dynamic-memory-allocation,C,Dynamic Memory Allocation,我正在编写一个函数,它增加了使用malloc创建的动态内存对象的大小。函数应该作为参数获取一个指针,指向要增加的内存块、块的当前大小以及块将要增加的量 大概是这样的: 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
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指向什么,我都希望函数能够工作。如何实现这一点?这种类型的函数不可能工作,因为
pnt
是本地函数,函数返回后新指针就会丢失。您可以接受类型为xxxxxx**
的参数,以便更新指针,但是您只能支持一种类型
真正的问题是,您正在为
realloc
编写一个不必要且有害的包装。只要直接使用realloc
,就可以了。没有办法通过包装使它更简单或更有效;它已经尽可能简单了。这种类型的函数不可能工作,因为pnt
是本地的,函数返回后新指针就会丢失。您可以接受类型为xxxxxx**
的参数,以便更新指针,但是您只能支持一种类型
真正的问题是,您正在为
realloc
编写一个不必要且有害的包装。只要直接使用realloc
,就可以了。没有办法通过包装使它更简单或更有效;它已经尽可能简单了。您将大小作为参数传入。您可以使用方便的宏使其看起来与您的函数相同:
#define getMoreSpace(P, SZ, ADD) getMoreSpaceFunc(&(P), sizeof(*(P)), (SZ), (ADD))
int getMoreSpace(void **pnt, size_t elem_size, int size, int add) {
*pnt = ...
}
编辑以显示便利宏还需要添加引用调用语义。将大小作为参数传入。您可以使用方便的宏使其看起来与您的函数相同:
#define getMoreSpace(P, SZ, ADD) getMoreSpaceFunc(&(P), sizeof(*(P)), (SZ), (ADD))
int getMoreSpace(void **pnt, size_t elem_size, int size, int add) {
*pnt = ...
}
编辑以显示便利宏还需要添加引用调用语义。将元素大小作为单独的参数传入:
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只是不适合动态类型信息
编辑
根据Steve的评论更改了pnt的类型。正如caf所指出的,即使按照Steve的“修复”,这也行不通。R.的权利;不要这样做 将元素大小作为单独的参数传入:
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只是不适合动态类型信息
编辑
根据Steve的评论更改了pnt的类型。正如caf所指出的,即使按照Steve的“修复”,这也行不通。R.的权利;不要这样做 @Stefanos:function参数是“局部变量”,因为当函数返回时,它们超出了作用域。将新值分配给
ptr
不会产生任何效果;事实上,编译器可以而且应该优化赋值。@paldepind:getMoreSpace
返回后,新内存块的地址丢失。这是内存泄漏。还要注意的是,即使这样做有效,调用方也必须检查成功或失败,但这与直接使用realloc
一样多。除非调用方实际拥有void*
变量并传递其地址,否则新版本将被破坏。当需要指向void*
的指针时,将指针传递给char*
或struct mystruct*
变量具有未定义的行为。执行类似于void*tmp=myptr的操作;getMoreSpace(&tmp,…);myptr=tmp代码>破坏了您试图实现的简化目的。就是不要这样做。直接调用realloc
并以标准方式检查错误是最简单的方法。剩下的只是基本的复杂性。@Stefanos:你完全错了。成功执行realloc
后,对象的新地址可能与传递的原始地址相同,也可能不同,如果它们不同,则原始地址可能不再用于任何用途。你为什么对一个你显然一无所知的问题发表评论?@paldepind:你不知道。在C语言中,无法使用函数实现您想要的功能。您可能会使用宏,但通常会遇到一些问题@Stefanos:你的答案不是C。@Stefanos:函数参数是“局部变量”,因为当函数返回时,它们超出了范围。将新值分配给ptr
不会产生任何效果;事实上,编译器可以而且应该优化赋值。@paldepind:getMoreSpace
返回后,新内存块的地址丢失。这是内存泄漏。还要注意的是,即使这样做有效,调用方也必须检查成功或失败,但这与直接使用realloc
一样多。除非调用方实际拥有void*
变量并传递其地址,否则新版本将被破坏。当需要指向void*
的指针时,将指针传递给char*
或struct mystruct*
变量具有未定义的行为。执行类似于void*tmp=myptr的操作;getMoreSpace(&tmp,…);myptr=tmp代码>破坏了您试图实现的简化目的。就是不要这样做。直接调用realloc
并以标准方式检查错误是最简单的方法。剩下的只是基本的复杂性。@Stefanos:你完全错了。成功执行realloc
后,对象的新地址可能与传递的原始地址相同,也可能不同,如果它们不同,则原始地址可能不再用于任何用途。你为什么对一个你显然一无所知的问题发表评论?@pald