tek*_*agi 7 c arrays pointers void
是否可以使用多种类型的数组malloc?
编辑:
目前我有:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define int(x) *((int *) x)
int main() {
void *a[10];
a[0] = malloc(sizeof(int));
int(a[0]) = 4;
char *b = "yola.";
a[1] = malloc(strlen(b)*sizeof(char));
a[1] = b;
printf("%d\n", int(a[0]));
printf("%s\n", a[1]);
}
Run Code Online (Sandbox Code Playgroud)
但它很乱.其他方法?
编辑:清理了一下.
Dmi*_*tri 17
确切地说,您不能拥有不同类型的数组.但是你可以通过许多不同的方式达到类似的效果(至少出于某些目的).
如果您只想将一些不同类型的值打包在一起,但值的数量和类型不会改变,您只需要一个struct并且可以按名称访问它们:
struct s_item {
int number;
char str[100];
} item;
item.number = 5;
strcpy(item.str,"String less than 100 chars");
Run Code Online (Sandbox Code Playgroud)
如果您知道可能使用的类型,则可以创建一个union或包含union的结构,以便可以使用该类型对其进行标记.然后,您可以创建这些数组.该type成员允许您稍后检查以查看存储在每个数组元素中的内容.
enum ElementType { et_str, et_int, et_dbl };
struct Element {
ElementType type;
union {
char *str;
int i;
double d;
}
};
struct Element *arr = malloc(sizeof(struct Element) * 3);
arr[0].type = et_str;
arr[0].str = strdup("String value"); /* remember to free arr[0].str */
arr[1].type = et_int;
arr[1].i = 5;
arr[2].type = et_dbl;
arr[2].d = 27.3;
/* access the values.. */
for (int i = 0; i < 3; i++) {
switch(arr[i].type) {
case et_str: printf("String: %s\n",arr[i].str); break;
case et_int: printf("Integer: %d\n",arr[i].i); break;
case et_dbl: printf("Double: %f\n",arr[i].d); break;
}
}
/* The strings are dynamically allocated, so free the strings */
for (int i = 0; i < 3; i++)
if (arr[0].type == et_str) free(arr[0].str);
/* free the malloc'ed array */
free(arr);
/* etc., etc. */
Run Code Online (Sandbox Code Playgroud)
这种方法可能会浪费空间,因为
如果你有另一种方法可以知道你在每个元素中存储了什么类型,你可以只使用裸结合而不用结构包装它.这个更紧凑,但每个元素仍然至少与联合中最大的类型一样大.
您还可以创建void *值数组.如果这样做,您将不得不以某种方式分配项目并将其地址分配给数组元素.然后,您需要将它们转换为适当的指针类型以访问项目.C不提供任何运行时类型信息,因此无法找出每个元素从指针本身指向的数据类型 - 您必须自己跟踪它.当您存储的类型很大并且它们的大小变化很大时,这种方法比其他方法紧凑得多,因为每个类型都与数组分开分配,并且只能给出该类型所需的空间.对于简单类型,您实际上并没有使用联合.
void **arr = malloc(3 * sizeof(void *));
arr[0] = strdup("Some string"); /* is a pointer already */
arr[1] = malloc(sizeof(int));
*((int *)(arr[1])) = 5;
arr[2] = malloc(sizeof(double));
*((double *)(arr[2])) = 27.3;
/* access the values.. */
printf( "String: %s\n", (char *)(arr[0]) );
printf( "Integer: %d\n", *((int *)(arr[1])) );
printf( "Double: %f\n", *((double *)(arr[2])) );
/* ALL values were dynamically allocated, so we free every one */
for (int i = 0; i < 3; i++)
free(arr[i]);
/* free the malloc'ed array */
free(arr);
Run Code Online (Sandbox Code Playgroud)
如果需要跟踪数组中的类型,还可以使用结构将类型与指针一起存储,类似于前面的union示例.再次,当存储的类型很大并且大小变化很大时,这才真正有用.
enum ElementType { et_str, et_int, et_dbl };
struct Element {
ElementType type;
void *data;
};
struct Element *arr = malloc(sizeof(struct Element) * 3);
arr[0].type = et_str;
arr[0].data = strdup("String value");
arr[1].type = et_int;
arr[1].data = malloc(sizeof(int));
*((int *)(arr[1].data)) = 5;
arr[2].type = et_dbl;
arr[2].data = malloc(sizeof(double));
*((double *)(arr[2].data)) = 27.3;
/* access the values.. */
for (int i = 0; i < 3; i++) {
switch(arr[i].type) {
case et_str: printf( "String: %s\n", (char *)(arr[0].data) ); break;
case et_int: printf( "Integer: %d\n", *((int *)(arr[1].data)) ); break;
case et_dbl: printf( "Double: %f\n", *((double *)(arr[2].data)) ); break;
}
}
/* again, ALL data was dynamically allocated, so free each item's data */
for (int i = 0; i < 3; i++)
free(arr[i].data);
/* then free the malloc'ed array */
free(arr);
Run Code Online (Sandbox Code Playgroud)