【问题标题】:safely resizing structs安全地调整结构的大小
【发布时间】:2011-06-14 09:08:31
【问题描述】:

当某些成员的大小在代码时未知时,我想要一些关于处理结构的安全方法的建议。

例如,我有一个名为“Channel”的结构。该结构有一个成员名称“AudioSourceOBJ”,它是指向名为“AudioSource”的其他结构类型数组的指针。在程序运行之前,我不知道每个通道有多少个 AudioSource。我就是这样处理的。

频道对象

struct channelobj {

        AudioUnitSampleType *leftoutput;
    AudioUnitSampleType *rightoutput;
    AudioSourceOBJ *audioSource;



};

音源

struct audiosourceobj {


    AudioUnitSampleType   *leftoutput;
    AudioUnitSampleType   *rightoutput;


};

可变大小结构的创建

void createInputs(ChannelOBJ channel,int numAudioInputs)
{
    channel->audioSource=(AudioSourceOBJ *)malloc(numAudioInputs * sizeof(AudioSourceOBJ));

    for (int i=0;i<numAudioInputs;i++)
    {
        AudioSourceOBJ obj;
        obj=newAudioSourceOBJ();
        channel->audioSource[i]=obj;

    }
}

我觉得这样可以吗?

我现在面临的问题是,即使我可以在我的通道结构中为正确数量的音频对象分配内存,但直到在程序的后期才会设置 audiosource 结构中的 leftoutput 和 rightoutput 数组。它们将填充少量数据,并且可能在应用程序的整个生命周期内改变大小和内容。

每次我想对单个音频对象进行更改时,我是否必须完全重新分配包含音频源的通道?

什么是安全的方法或有更好的方法?

【问题讨论】:

    标签: c struct malloc


    【解决方案1】:

    “每次我想对单个音频对象进行更改时,我是否必须完全重新分配包含音频源的通道?”

    没有。例如,您可以像这样替换 ith 音频源的左侧输出:

    free(channel->audioSource[i].leftoutput);
    channel->audioSource[i].leftoutput = malloc(newSize * sizeof(AudioUnitSampleType));
    

    甚至:

    AudioUnitSampleType *tmp = realloc(channel->audioSource[i].leftoutput,
        newSize * sizeof(*tmp));
    if (tmp == 0) { /* handle the error */ }
    channel->audioSource[i].leftoutput = tmp;
    

    顺便说一句,如果您不发布真实代码,由于示例中的错误,答案可能会包含错误。

    在您的代码中,指针和对象之间似乎有些混淆,例如channel 参数的类型为ChannelOBJ,那么您将其当作指针来使用。这是一个错误,还是ChannelOBJstruct channelobj* 的类型定义?通常最好使用 typedef 来隐藏某个东西是指针。

    如果 AudioUnitSampleType 同样是指针类型,那么我上面的第一个代码 sn-p 是不完整的,因为它还需要释放数组元素指向的旧对象,并分配新对象。第二个需要释放旧的根据大小是增加还是减少分配新的。

    【讨论】:

    • 是 ChannelOBJ 是 struct channelobj 的 typedef。在这种情况下,您为什么建议不要使用 typedef?
    • @dubbeat:因为 C 不是 Java ;-p。实际上,因为人们经常需要知道给定类型是否“真的”是一个指针,每当他们查看对其起作用的代码时。例如,为了编写我的代码 sn-ps,我需要知道 AudioUnitSampleType 是什么。即使您使用 ChannelOBJ 作为 API 客户端的完全不透明类型,并且这就是他们使用的头文件中出现的内容,我也会使用 struct channelobj* 作为函数实现中的参数,因为在函数中我需要知道它是一个指针(使用-&gt; 而不是.)。
    • 因此,隐藏ChannelOBJ 是指针可能对于您的 API 的客户来说是一个有用的抽象,如果他们将其视为无意义的句柄并仅使用它来传递进入你的功能。但是一旦你进入 createInputs 函数,它就不是一个有用的抽象,它只是隐藏了我(读者或程序员)需要知道的东西。抽象应该隐藏我不需要需要知道的东西。
    • 为详尽的解释点赞。
    【解决方案2】:

    不,您不必调整分配的AudioSourceObj 结构块的大小。 leftoutputrightoutput 只是固定大小的指针(不是可变大小的数组),可以通过单独的 malloc 分配地址:

    channel->audioSource[i].leftoutput = malloc(5 * sizeof(AudioUnitSampleType));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 2017-01-01
      • 2015-06-22
      相关资源
      最近更新 更多