Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用C获得同一函数中不同类型的大小?_C_Dynamic Memory Allocation - Fatal编程技术网

如何使用C获得同一函数中不同类型的大小?

如何使用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

我正在编写一个函数,它增加了使用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 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