将类型作为参数传递

时间:2016-08-17 21:51:11

标签: c

ETA:这不是关于malloc()或内存分配,而是关于将类型作为参数传递,如:

ptr = getMem(char, 1000);

我使用malloc()作为一个简单的例子。

这可能是一个愚蠢的问题,或者我可能遗漏了一些东西。

让我们想象一下,我想写一个简单的函数来分配一些内存,而不是任何特定类型的内存,但更灵活。

就像说,我想分配1000个字符并返回。所以我想要一个我可以这样称呼的函数:

fprintf(stdout, "%s\n", va_arg(l, char));

将实际类型作为参数,这可能很有用。

现在我知道像va_arg()这样的宏可以做到这一点:

type va_arg(va_list ap, type)

所以我稍微调查一下,这一切都很模糊。我发现了这个:

ap − This is the object of type va_list with information about the additional arguments and their retrieval state. This object should be initialized by an initial call to va_start before the first call to va_arg.

type − This is a type name. This type name is used as the type of the expression, this macro expands to.
  

参数

va_list

你可以看到第一个参数的类型定义为type, 但第二个参数,即我感兴趣的参数 - 只是指定为#include <stdio.h> #include <stdlib.h> #include <string.h> void *getMem(type, int size) { return malloc(sizeof(type) * size); } int main(void) { void *mem; mem = getMem(1000, char); if (mem == NULL) { perror("malloc()"); exit(EXIT_FAILURE); } fprintf(stdout, "Memory allocated successfully!\n"); free(mem); exit(EXIT_SUCCESS); }

所以它开始让我烦恼,我一直在乱用这样的bum代码:

{%-

我一直在嗅探包含文件试图解决这个问题,但无济于事,有没有办法可以做到这一点?

很抱歉,如果它有点模糊或荒谬,但如果va_arg()可以做到这一点,我认为我应该也可以。

很有责任。

4 个答案:

答案 0 :(得分:2)

使用CPP宏执行此操作:

#define getMem(type, size) \
    malloc(sizeof(type) * size)

但是,就个人而言,我更喜欢这个:

#define getMemOf(ptr, size) \
    ptr = malloc(sizeof(*ptr) * size)

// invoke with:
    getMemOf(ptr, 1000);

答案 1 :(得分:2)

C99 中的

_Generic C11可能会提供接近OP需求的东西。

示例:代码想要分配公共整数类型的最大值。

#define integer_max(X) _Generic((X), \
  unsigned long long: ULLONG_MAX, \
  long long: LLONG_MAX, \
  unsigned long: ULONG_MAX, \
  long: LONG_MAX, \
  unsigned: UINT_MAX, \
  int: INT_MAX, \
  unsigned short: USHRT_MAX, \
  short: SHRT_MAX, \
  unsigned char: UCHAR_MAX, \
  signed char: SCHAR_MAX, \
  char: CHAR_MAX, \
  _Bool: 1, \
  default: 1/0 \
  )

  // Here the _type_ of `x` is used by integer_max(), not its value.
  some_integer_type x = integer_max(x);

答案 2 :(得分:0)

malloc()不需要知道要正常工作的类型,只需知道该类型的 size

如果代码想要确保大小计算中没有溢出,则可以进行检查。

void *getMem(size_t element_count, size_t type_size) {
  if (element_count > SIZE_MAX/type_size) return NULL;
  return malloc(element_count * size);
}

// usage example
size_t element_count, 
void * p = getMem(element_count, sizeof (char));

如果想要零内存,只需使用calloc()

// usage example
size_t element_count, 
void * p = calloc(element_count, sizeof (char));

建议代码不要使用void *指针,并分别表达类似char的类型。相反,声明一个非void类型的指针。

#define ALLOCATE_ASSIGN(addr_ptr, count) (*(addr_ptr)=malloc(sizeof **(addr_ptr) * count))

some_type *mem;
ALLOCATE_ASSIGN(&mem, element_count);

答案 3 :(得分:0)

无论如何,你最终会用sizeof来做这件事。我刚刚在Visual Studio中检查了这个,并且Microsoft将其定义为(跨多个定义)

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_arg _crt_va_arg

你可以在vadefs.h找到这些。长话短说,你不会在某个地方使用sizeof,所以你应该在最简单的地方使用它。就我个人而言,我认为只是将大小传递给你的getMem函数而不是类型将从长远来看让你更加头疼。