这是一个相当基本的问题,由于某种原因,目前正确的解决办法让我摆脱困境。我正在处理第三方SDK,它声明了以下结构:
struct VstEvents
{
VstInt32 numEvents; ///< number of Events in array
VstIntPtr reserved; ///< zero (Reserved for future use)
VstEvent* events[2]; ///< event pointer array, variable size
};
即使这是一个“可变大小”的数组,它也是静态声明的。很明显,如果我创建一个VstEvents对象,将numEvents设置为某个东西,然后继续并开始将它们添加到数组中,这将导致内存损坏。
那么我该如何正确处理这样的结构呢?我应该分配自己的VstEvent *数组,然后将事件[0]指向它吗?
答案 0 :(得分:4)
你需要预先分配一大块内存,足以包含整个内容+你想要的任何其他记录......
struct VstEvents
{
VstInt32 numEvents; ///< number of Events in array
VstIntPtr reserved; ///< zero (Reserved for future use)
VstEvent* events[2]; ///< event pointer array, variable size
};
#define numEventsRequired 10
VstEvents *vstEvents = (VstEvents*)malloc(sizeof(VstEvents) + sizeof(VstEvent*)*(numEventsRequired-2));
vstEvents->numEvents = numEventsRequired;
答案 1 :(得分:1)
如果你知道有多少你可以用
分配它struct VstEvents *evnts;
evnts = (struct VstEvents*)malloc(sizeof(struct VstEvents) +
numEvents*sizeof(VstEvent*));
这将分配2个额外广告位
答案 2 :(得分:0)
您的第三方库有点奇怪。您需要区分两种“可变大小的数组”
分配数组时已知大小,此后永远不会更改。这是一个简单的案例,我在下面展示了一个C99成语。
在分配数组时,最终大小未知,数组在其生命周期内可能需要增长。对于这样的事情,我建议你在Dave Hanson C Interfaces and Implementations的源文件seq.c中查看Seq_T的实现。你可以很容易地调整他的代码。
如果您知道分配时的大小,那么C99的成语就是:
struct VstEvents
{
VstInt32 numEvents; ///< number of Events in array
VstIntPtr reserved; ///< zero (Reserved for future use)
VstEvent* events[]; ///< event pointer array, variable size
};
struct VstEvents *alloc_vst_events(int num_events) {
struct VstEvents *p =
malloc(sizeof(*p) + num_events * sizeof(p->events[0]));
return p;
}
关键是结构中的奇怪数组大小未指定。需要C99。
由于你会遇到第三方的怪异,我会尝试这个:
#define NELEMS(A) (sizeof(A) / sizeof((A)[0]))
struct VstEvents *alloc_vst_events(int num_events) {
struct VstEvents *p;
int events_needed = num_events - NELEMS(p->events);
p = malloc(sizeof(*p) + events_needed * sizeof(p->events[0]));
return p;
}
免责声明:我没有通过编译器推送此代码。欢迎更正。
答案 3 :(得分:-1)
结构声明的是指向VstEvent对象的指针数组(大小为2)。您应该分配一个VstEvent并将其分配给events [0],将numEvents设置为1.如果您有2个VstEvent,则分配另一个VstEvent,将其分配给事件[1],并将numEvents设置为2.如果您需要2个以上,然后你需要对VstEvents进行realloc以增加其大小,以便事件包含你需要的指针数量,并根据需要分配给2,3,4 ......或者,如果您提前知道需要存储多少事件,则最初可以将其分配为@ SDX2000显示。
我认为基本的想法是,为了方便起见,他们用大小2声明它,这样如果你只有1或2,你就不需要做一个额外的malloc来调整events数组的大小。