безопасное изменение размеров структур - PullRequest
0 голосов
/ 14 июня 2011

Я хотел бы получить несколько советов о безопасных способах работы со структурами, когда размер некоторых членов неизвестен во время кода.

Например, у меня есть Struct Named "Channel".Эта структура имеет имя члена «AudioSourceOBJ», которое является указателем на массив другого типа структуры с именем «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;

    }
}

Я думаюэто нормально?

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что, хотя я могу назначить память для правильного количества аудиообъектов в моей структуре канала, массивы leftoutput и rightoutput в структуре аудиосообщения не будут установлены, покапозже в программе.Они будут заполнены заниженным объемом данных и, вероятно, будут меняться по размеру и содержанию в течение всего жизненного цикла приложения.

Придется ли мне полностью перераспределять канал, содержащий аудиоресурсы, каждый раз, когда я захочувнести изменения в один аудио объект?

Какой безопасный способ сделать это или есть лучший подход?

Ответы [ 2 ]

2 голосов
/ 14 июня 2011

«Придется ли мне полностью перераспределять канал, содержащий аудиоисточник, каждый раз, когда я хочу внести изменения в один аудиообъект?»

Нет. Например, вы можете заменить левый выход i-го аудиоисточника следующим образом:

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, тогда вы используете его как указатель. Это ошибка или ChannelOBJ typedef для struct channelobj*? Как правило, , а не , лучше скрывать, что что-то является указателем с помощью typedef.

Если AudioUnitSampleType также является типом указателя, то мой первый приведенный выше фрагмент кода будет неполным, поскольку тогда также потребуется освободить старые объекты, на которые указывают элементы массива, и выделить новые. Второй должен освободить старых или выделить новых в зависимости от того, увеличивается или уменьшается размер.

1 голос
/ 14 июня 2011

Нет, вам не придется изменять размер выделенного блока AudioSourceObj структур. leftoutput и rightoutput - это просто указатели фиксированного размера (не массивы переменного размера), и им можно присвоить адрес, выполнив отдельный malloc:

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