Нет, нет способа получить эту информацию без сильной зависимости от деталей реализации malloc
. В частности, malloc
может выделить больше байтов, чем вы запрашиваете (например, для эффективности в конкретной архитектуре памяти). Было бы гораздо лучше изменить код так, чтобы вы явно отслеживали n
. Альтернатива - это по крайней мере столько же редизайна и гораздо более опасного подхода (учитывая, что он нестандартен, злоупотребляет семантикой указателей и станет кошмаром обслуживания для тех, кто придет после вас): длина n
по адресу malloc'd, за которым следует массив. Распределение будет тогда:
void *p = calloc(sizeof(struct mystruct) * n + sizeof(unsigned long int),1));
*((unsigned long int*)p) = n;
n
теперь хранится в *((unsigned long int*)p)
, а начало вашего массива теперь
void *arr = p+sizeof(unsigned long int);
Редактировать: Просто чтобы сыграть в адвокат дьявола ... Я знаю, что все эти "решения" требуют доработок, но давайте поиграем.
Конечно, решение, представленное выше, является просто хакерской реализацией (хорошо упакованной) структуры. Вы могли бы также определить:
typedef struct {
unsigned int n;
void *arr;
} arrInfo;
и передайте arrInfo
с, а не сырые указатели.
Теперь мы готовим. Но пока вы меняете дизайн, зачем останавливаться на достигнутом? Что вам действительно нужно, так это абстрактный тип данных (ADT). Любой вводный текст для класса алгоритмов и структур данных сделает это. ADT определяет открытый интерфейс типа данных, но скрывает реализацию этого типа данных. Таким образом, публично ADT для массива может выглядеть как
typedef void* arrayInfo;
(arrayInfo)newArrayInfo(unsignd int n, unsigned int itemSize);
(void)deleteArrayInfo(arrayInfo);
(unsigned int)arrayLength(arrayInfo);
(void*)arrayPtr(arrayInfo);
...
Другими словами, ADT - это форма инкапсуляции данных и поведения ... другими словами, она примерно настолько близка, насколько вы можете приблизиться к объектно-ориентированному программированию, используя прямой C. Если вы не застряли на платформе, которая не имеет компилятора C ++, вы могли бы с таким же успехом использовать просто STL std::vector
.
Там мы взяли простой вопрос о C и оказались на C ++. Боже, помоги нам всем.