如何在 C 中对 malloc() 数组进行一行赋值?

How to do one line assignment to malloc() arrays in C?

在 C 中,我可以像这样在堆栈上初始化一个数组:

SOME_DATA_TYPE* x = (SOME_DATA_TYPE[5]) {v1, v2, v3, v4, v5};

是否有类似的单行方法来为堆上的 malloc()-ed 数组赋值?

SOME_DATA_TYPE* y = malloc(sizeof(SOME_DATA_TYPE)*5);  
// what comes here?  

或者我是否必须遍历数组并单独赋值?

您可以像这样定义一个函数:

#include <stdarg.h>
#include <stdlib.h>

int * intMallocInit (int length, ...) {
   // Initialize Variable Arguments
   va_list args;
   va_start (args, length); 

    // Allocate Memory
    int * arr = malloc (sizeof(int) * length);
    if (arr == NULL) return NULL;

    // Initialize Array
    for (int i = 0; i < length; i++) {
        arr[i] = va_arg(args, int);
    }

    // Clean Up and Return
    va_end(args)
    return arr;
}

我们可以这样称呼它:

int len = 3;
int * myArray = intMallocInit (len, 4, 5, 2);
if (myArray == NULL) return 0; 

for (int i = 0; i < len; i++) {
    printf("%d,", myArray [i]);
}

输出: 4,5,2,

注意:我们也可以定义floatMallocInit()等,只需将上述函数中的每个"int"实例替换为"float"

你也可以使用 void 指针,或 enum& switch,但我不会去那里。

未经测试的一般功能尝试 我确定围绕开关有一个聪明的工作,但这是我能想到的。

#include <stdarg.h>
#include <stdlib.h>
enum {INT, FLOAT /* etc...*/}

 int getSize(int type) {
     int typeSize = 0;
     switch (type) {
        case INT: 
             typeSize = sizeof (int);
             break;
        case FLOAT:
             typeSize = sizeof (float);
             break;
        // Etc...
        default:
             return -1;
    }
    return typeSize;
 }


void * mallocInit (int type, int length, ...) {
   // Initialize Variable Arguments
   va_list args;
   va_start (args, length); 

    // Get Size of type
    int typeSize = getSize(type);
    if (typeSize == -1) return NULL;

    // Allocate Memory
    void * arr = malloc (typeSize * length);
    if (arr == NULL) return NULL;

    // Initialize Array, Maybe va_copy can be used? No good reference
    for (int i = 0; i < length; i++) {
         switch(type) {
            case INT:
             arr[i] = va_args(args, int);
             break;
            // Etc..
        }
    }

    // Clean Up and Return
    va_end(args)
    return arr;
}

调用

float myArray = mallocInit (FLOAT, 3, 1, 5, 7);

“初始化”malloc()结果的第一个问题是分配可能失败。这里 y 初始化 为某个指针值。引用的数据仍然不确定。

#define  element_count  5
SOME_DATA_TYPE *y = malloc(sizeof *y * element_count);
if (y == NULL) Handle_OutOfMemory();

使用C11,代码可以使用复合文字来设置,而不是初始化y指向的数据。

memcpy(y, (SOME_DATA_TYPE[element_count]) {v1, v2, v3, v4, v5}, sizeof *y * element_count);

使用 direct 单行而不检查分配将不是健壮的编程。

// one-liner, but not robust code
SOME_DATA_TYPE *y = memcpy(malloc(sizeof *y * element_count), 
    (SOME_DATA_TYPE[element_count]) {v1, v2, v3, v4, v5}, sizeof *y * element_count);

注意代码使用 sizeof *pointer_variable * element_count 而不是 sizeof (pointer_variable_dereferenced_type) * element_count 更易于编码、不易出错、更易于审查和维护。两种方法都行得通。

在不偏离自然 C 内存管理哲学的情况下,一种方法是使用类似 memdup 的函数。由于它不是标准的,您可能需要自己实现它

SOME_DATA_TYPE *y = memdup(
  (SOME_DATA_TYPE[5]) {v1, v2, v3, v4, v5},
  5 * sizeof(SOME_DATA_TYPE));