在您的示例中存在错误:未分配结构,create 函数未返回分配的结构。在分配 myStruct 之前,您不能这样做:myStruct->packet = (int *)malloc(length * sizeof(int));。
我编写了两个示例,其中使用enum 枚举结构中packet 数组的类型,使用union packet 管理
不同类型的数据。
结构myStruct 将包含有关packet 联合的内容类型及其数组维度的信息。
函数create,在第一个示例中,仅使用一个malloc 来分配结构空间和数据包空间。这种方式更简单地解除分配结构。此外,create 可能会在参数err 上返回错误以指示错误情况,另一方面,如果出现错误,则在此版本的第一个示例中,函数的返回值应为NULL。
如果您不需要分配结构,我已经编写了第二个示例,它只为联合 packet 分配空间(上面的第二个示例)。这里函数create为一个已经分配的结构分配packet,如果发生错误则返回0或错误值。
这里是第一个示例:
#include <stdio.h>
#include <stdlib.h>
typedef enum myType {
myTypeDouble,
myTypeInt
} myType;
typedef struct myStruct {
myType myType;
size_t length;
// int message; in this sample this has no mean!
union {
int * i;
double * d;
} packet;
} myStruct;
myStruct * create(myType mtype, size_t length, int *err)
{
myStruct * ms = NULL;
int retVal=0;
size_t mlen = sizeof (myStruct);
switch(mtype) {
case myTypeInt:
mlen += sizeof(int)*length;
break;
case myTypeDouble:
mlen += sizeof(double)*length;
break;
default:
mlen=0;
retVal=1;
break;
}
if (mlen) {
ms = malloc(mlen); // One malloc allocates struct and packet.
if (ms != NULL) {
ms->length = length;
ms->myType=mtype;
/* Don't care myType, the usable space is after
the structure dimension then ms->packet.i=[...]
should be also ms->packet.d=(double *)(ms+1);
*/
ms->packet.i=(int *)(ms+1);
} else {
retVal=2;
}
}
if (err)
*err=retVal;
return ms;
}
int main(void) {
#define PACKLEN 20
myStruct * ms[2]={NULL,NULL};
int err=0;
int i;
ms[0]=create(myTypeInt,PACKLEN,&err);
if (err)
return 1;
ms[1]=create(myTypeDouble,PACKLEN,&err);
if (err) {
if (ms[0])
free(ms[0]);
return 2;
}
for (i=0;i<PACKLEN;i++) {
ms[0]->packet.i[i] = i*2+1;
ms[1]->packet.d[i] = 2.1*(double)(i+1);
}
for (i=0;i<PACKLEN;i++) {
printf("%d ",ms[0]->packet.i[i]);
}
puts("");
for (i=0;i<PACKLEN;i++) {
printf("%g ",ms[1]->packet.d[i]);
}
puts("");
if (ms[0])
free(ms[0]);
if (ms[1])
free(ms[1]);
}
这里是第二个示例:
#include <stdio.h>
#include <stdlib.h>
typedef enum myType {
myTypeDouble,
myTypeInt
} myType;
typedef struct myStruct {
myType myType;
size_t length;
// int message; don't care in this sample.
union {
int * i;
double * d;
} packet;
} myStruct;
int create(myStruct * ms, myType mtype, size_t length)
{
int retVal=0;
size_t mlen = 0;
if (!ms) {
return 1;
}
switch(mtype) {
case myTypeInt:
mlen = sizeof(int)*length;
break;
case myTypeDouble:
mlen = sizeof(double)*length;
break;
default:
mlen=0;
retVal=2;
break;
}
if (mlen) {
/* Don't care myType! ms->packet.i=[...]
should be also ms->packet.d=malloc(mlen);
*/
ms->packet.i=malloc(mlen);
if (ms) {
ms->length = length;
ms->myType=mtype;
} else {
retVal=3;
}
}
return retVal;
}
int main(void) {
#define PACKLEN 20
myStruct ms[2];
int err=0;
int i;
ms[0].packet.i=NULL;
ms[1].packet.d=NULL; // Although the use of .i has the same behaviour
err=create(&ms[0],myTypeInt,PACKLEN);
if (err)
return 1;
err=create(&ms[1],myTypeDouble,PACKLEN);
if (err) {
if (ms[0].packet.i)
free(ms[0].packet.i);
return 2;
}
for (i=0;i<PACKLEN;i++) {
ms[0].packet.i[i] = i*2+1;
ms[1].packet.d[i] = 2.1*(double)(i+1);
}
for (i=0;i<PACKLEN;i++) {
printf("%d ",ms[0].packet.i[i]);
}
puts("");
for (i=0;i<PACKLEN;i++) {
printf("%g ",ms[1].packet.d[i]);
}
puts("");
if (ms[0].packet.i)
free(ms[0].packet.i);
// Although the use of packet.i has the same behaviour.
if (ms[1].packet.d)
free(ms[1].packet.d);
}