Глядя на C ++ new [] cookie. Насколько переносим этот код? - PullRequest
2 голосов
/ 04 мая 2010

Я придумал это как быстрое решение проблемы отладки - у меня есть переменная указателя и ее тип, я знаю, что она указывает на массив объектов, размещенных в куче, но я не знаю, сколько. Поэтому я написал эту функцию для просмотра файла cookie, в котором хранится количество байтов при выделении памяти в куче.

template< typename T >
int num_allocated_items( T *p )
{
return *((int*)p-4)/sizeof(T);
}

//test
#include <iostream>
int main( int argc, char *argv[] )
{
    using std::cout; using std::endl;
    typedef long double testtype;
    testtype *p = new testtype[ 45 ];

    //prints 45
    std::cout<<"num allocated = "<<num_allocated_items<testtype>(p)<<std::endl;
    delete[] p;
    return 0;
}

Я бы хотел знать, насколько переносим этот код.

Ответы [ 3 ]

11 голосов
/ 04 мая 2010

Это даже удаленно не портативно.

Реализация может вести бухгалтерию кучи по своему усмотрению, и нет абсолютно никакого способа портативно получить размер распределения кучи, если вы сами не отслеживаете это (что вам следует делать).

2 голосов
/ 04 мая 2010

Вы можете глобально перегрузить новые / удалить операторы в массиве и поместить размер в область памяти. Вы получаете портативное решение.

В приведенном ниже коде показано, как:

void * operator new [] (size_t size)
{
    void* p = malloc(size+sizeof(int));
    *(int*)p = size;
    return (void*)((int*)p+1);
}

void operator delete [] (void * p)
{
    p = (void*)((int*)p-1);
    free(p);
}

template<typename T>
int get_array_size(T* p)
{
    return *((int*)p-1)/sizeof(T);
}


int main(int argc, char* argv[])
{
    int* a = new int[200];
    printf("size of a is %d.\n", get_array_size(a));
    delete[] a;
    return 0;
}

Результат:

   size of a is 200.
2 голосов
/ 04 мая 2010

Не переносимо.Но почему бы не использовать std::vector?Затем вы можете напрямую спросить, сколько элементов он содержит, и вам не нужно беспокоиться об управлении памятью и безопасности исключений.

...