如何在 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));
在 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));