Этот код выглядит немного запутанным: вы передаете "sizeof IMyInterface" в malloc (), который будет размером в памяти экземпляра IMyInterface, а не указателем на него: вы вполне могли бы иметь в виду "sizeof IMyInterface * "если вы хотите выделить память для указателя.
Однако, глядя на это, это тоже не имеет никакого смысла: не лучше ли вообще не выполнять malloc ()? Последний аргумент SafeArrayGetElement () - это указатель на память, в которой будет храниться результат, поэтому содержимое l (указатель, возвращаемый malloc ()) будет просто перезаписано (поэтому free () дает вам сбой). Другими словами, только это должно работать:
IMyInterface *l;
SafeArrayGetElement(array,&i, &l);
Не зная точно, что находится в массиве, трудно быть уверенным, но похоже, что вас смущает старая проблема C / C ++, заключающаяся в разнице между указателями и объектами, на которые они указывают.