safely resizing structs
I would like some advice on safe ways to deal with struct's when the size of certain members are not known at code time.
For example I have a Struct Named "Channel". This struct has a member name "AudioSourceOBJ" which is a pointer to an an array of other struct type named "AudioSource". I wont know how many AudioSources I will have per channel until the program is run. I deal with that like this.
channel object
struct channelobj {
AudioUnitSample开发者_如何学运维Type *leftoutput;
AudioUnitSampleType *rightoutput;
AudioSourceOBJ *audioSource;
};
audiosource
struct audiosourceobj {
AudioUnitSampleType *leftoutput;
AudioUnitSampleType *rightoutput;
};
creation of variable sized structs
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;
}
}
I think this is o.k?
The problem I am now facing is that even though I can assign memory for the correct number of audio objects in my channel struct, the leftoutput and rightoutput arrays in the audiosource struct will not be set until later in the program. They will be filled with an undermined amount of data, and are likely to change in size and content throughout the lifetime of the application.
Will I have to completely re malloc the channel containing the audiosource every time I want to make changes to a single audio object?
What is a safe way to do this or is there a better approach?
"Will I have to completely re malloc the channel containing the audiosource every time I want to make changes to a single audio object?"
No. You could for example replace the left output of the i
th audio source like this:
free(channel->audioSource[i].leftoutput);
channel->audioSource[i].leftoutput = malloc(newSize * sizeof(AudioUnitSampleType));
Or even:
AudioUnitSampleType *tmp = realloc(channel->audioSource[i].leftoutput,
newSize * sizeof(*tmp));
if (tmp == 0) { /* handle the error */ }
channel->audioSource[i].leftoutput = tmp;
By the way, if you don't post real code, it's possible that answers will contain errors due to errors in your examples.
There seems to be some confusion in your code between pointers and objects, for example the channel
parameter is of type ChannelOBJ
, then you use it as if it's a pointer. Is this an error, or is ChannelOBJ
a typedef for struct channelobj*
? It's generally better not to conceal that something is a pointer using a typedef.
If AudioUnitSampleType is likewise a pointer type, then my first code snippet above is incomplete, since it would then also be necessary to free the old objects pointed to by the elements of the array, and allocate new ones. The second one needs to free old ones or allocate new ones according to whether the size is being increased or decreased.
No, you won't have to resize the allocated block of AudioSourceObj
structs. leftoutput
and rightoutput
are merely pointers of a fixed size (not variable-sized arrays) and can be assigned an address by doing a separate malloc
:
channel->audioSource[i].leftoutput = malloc(5 * sizeof(AudioUnitSampleType));
精彩评论