如何将数据存储在可变长度数组中而不会导致内存损坏?

时间:2008-12-11 12:07:33

标签: c memory-management

这是一个相当基本的问题,由于某种原因,目前正确的解决办法让我摆脱困境。我正在处理第三方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]指向它吗?

4 个答案:

答案 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数组的大小。