"Bertel Brander" <bertel@post4.tele.dk> wrote in message 
news:42c44000$0$274$edfadb0f@dread11.news.tele.dk...
> Mogens Hansen wrote:
>> "Bertel Brander" <bertel@post4.tele.dk> wrote in message 
>> news:42c308be$0$261$edfadb0f@dread11.news.tele.dk...
>>
>> [8<8<8<]
>>
>>>Ja, jeg kan godt gemme information om hvor mange bytes, der skulle
>>>allokeres, men jeg er ikke sikker på at der er nogen entydig
>>>sammenhæng mellem antallet af bytes og antallet af elementer i
>>>array'et.
>>>new[] operatoren kender normalt ikke typen på det der skal allokeres
>>>og kan dermed ikke beregne antallet af elementer.
>>>delete[] får måske en pointer til en afledt class, og så kan den vel
>>>heller ikke beregne antallet.
>>
>>
>> Du kender typen i den template funktion der skal frigive arrayet.
>> Dermed kender du størrelsen på hvert objekt og kan du beregne antal 
>> objekter.
>
> Desværre er det ikke så let.
> Jeg lavede et lille test project:
>
> #include <iostream>
> #include <new>
>
> enum Whatever
> {
>    Something
> };
>
> class X
> {
> public:
>    X() : x(Next++)
>    {}
>    ~X()
>    {}
>    int x;
>    static int Next;
> };
>
> int X::Next;
>
> void *operator new(size_t aSize)
> {
>    return malloc(aSize);
> }
>
> void *operator new[](size_t aSize)
> {
>    return malloc(aSize);
> }
>
> void *operator new[] (size_t aSize, Whatever aWhatever)
> {
>    std::cout << aSize << std::endl;
>    size_t *p = (size_t *)malloc(aSize + sizeof(size_t));
>    *p = aSize;
>    p += 1;
>    std::cout << "New[] returning: " << p << std::endl;
>    return p;
> }
>
> template<typename T> void destroy(T *t)
> {
>    std::cout << "destroy receiving: " << t << std::endl;
>    size_t n = *(size_t *)((char *)t - sizeof(size_t));
>    std::cout << n << " " << sizeof(T) << std::endl;
>    for(size_t i = 0; i < n/sizeof(T); i++)
>       t[i].~T();
> }
>
> int main()
> {
>    X *p;
>    p = new(Something) X[4];
>    destroy(p);
>    p = new(Something) X[5];
>    destroy(p);
> }
>
> Når jeg kører det kan jeg se at den addresse som new returnerer
> IKKE er den adresse om destroy får.
Det lyder underligt.
Jeg kan ikke hurtigt se hvad der er galt - men det er muligt.
I går skrev jeg noget næsten tilsvarende (det var det udkommenterede kode 
der kørte).
#include <new>
#include <iostream>
using namespace std;
class foo
{
public:
   foo()
      {  cout << "foo::foo(0x" << hex << this << ")" << endl;   }
   ~foo()
      {  cout << "foo:

foo(0x" << hex << this << ")" << endl;  }
};
enum tag_my_memory_pool
{
   MMP
};
void* operator new [] (size_t size, tag_my_memory_pool) throw 
(std::bad_alloc)
{
// void*    mem = operator new(size + sizeof(size_t));
//   size_t*  s = reinterpret_cast<size_t*>(mem);
// *s = size;
// return reinterpret_cast<char*>(mem) + sizeof(size_t);
   return operator new (size);
}
void operator delete [] (void* mem, tag_my_memory_pool)
{
 operator delete (reinterpret_cast<char*>(mem) - sizeof(size_t));
}
template <typename T, typename P>
void delete_array_pool(T* first_obj, P pool)
{
 if(!first_obj)
  return;
 void*   mem = first_obj;
   size_t*     s = reinterpret_cast<size_t*>(reinterpret_cast<char*>(mem) - 
sizeof(size_t));
 const size_t size = (*s)/*/sizeof(foo)*/;
 for(size_t i = 0; size != i; ++i) {
  T* t = &first_obj[size-i-1];
  t->~T();
 }
 operator delete [] (first_obj, pool);
}
int main()
{
   foo*  fp = new (MMP) foo[7];
   delete_array_pool (fp, MMP);
}
Der var det samme adresse "operator new []" returnerede som 
"delete_array_pool" fik.
Det gik også fint nok med at skrive størrelsen på blokken i "operator new 
[]".
MEN, engentligt ikke overraskende, skriver implementeringerne (compilerne) 
som jeg prøvede også i området før den adresse som "operator new []" 
returner. Og egentligt ikke overraskende skriver den hvormange elementer der 
er i arrayet 
Således virker den kode der ikke er udkommenteret fint på de 2 compilere jeg 
prøvede med - men det er _ikke_ portabelt eller på nogen måde 
veldokumenteret at det burde virke.
> Man kunne måske finde addressen, men koden skal helst være
> rimelig portabelt.
>
>> Måske var det en ide at overveje at bruge "std::vector" med en speciel 
>> allokator.
>
> Der bruges en del std::vector og std::list, som alle skal bruge en
> speciel allokator, desværre er der en del char/int/whatever *,
> som ikke kan laves om til std::vector.
Ting (char/int/whatever) der ligger i en std::vector kan sagtens overføres 
til funktioner der forventer et array af ting.
Men det hjælper måske ikke på dit problem.
Venlig hilsen
Mogens Hansen