Boost logo

Boost :

Subject: Re: [boost] How to get the size of an C-array?
From: Schrader, Glenn (gschrad_at_[hidden])
Date: 2009-10-14 17:43:10

> -----Original Message-----
> From: boost-bounces_at_[hidden] [mailto:boost-bounces_at_[hidden]]
> On Behalf Of vicente.botet
> Sent: Wednesday, October 14, 2009 4:54 PM
> To: boost_at_[hidden]
> Subject: Re: [boost] How to get the size of an C-array?
> Hi Andrey,
> ----- Original Message -----
> From: "Andrey Semashev" <andrey.semashev_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Wednesday, October 14, 2009 7:18 PM
> Subject: Re: [boost] How to get the size of an C-array?
> >
> > vicente.botet wrote:
> >> Hi,
> >>
> >> On TBoost.STM, I need to do something before deleting an array on each
> one of the elements of the array, or more precissely with the address of
> each one of the elements.
> >>
> >> T* ptr = new T[3];
> >>
> >> // in another file, the number of elements to which ptr points is
> unknown.
> >> // before deleting
> >> for (size_t i=0; i< 'ptr size'; ++i) {
> >> // do something with &ptr[i]
> >> }
> >> delete [] ptr;
> >>
> >> As the number of elemenst is unknow in the separated unit, I have no
> mean to iterate on ptr to get the address of the elements.
> >>
> >> The C++ compiler or the C++ standard library knows this number of
> elements as it needs to call the destructor of each element when deleting
> the pointer. Is there something in Boost or a portable way to recover the
> number of elements of the array, maybe overloading the new [] operator and
> prefixing the allocate storage with some information? But what information
> can be stored so the implementation is portable?
> >
> > There is no portable way to acquire the dynamic array length. IMO, there
> > are two practical solutions for this:
> >
> > 1. Put everything you need into T's destructor. If T is a third party
> > type then a wrapper class around T can serve the purpose.
> Well, the problem is that we need to do something before the destructor is
> called. When deleting an array of transactional objects we need to mark
> each one of the elements as if they were written, so the conclict
> detection cat detect other threads been written on a specific array
> element.
> > 2. Use a range wrapper instead of a raw pointer to the array.
> This is equivalent to say that we can not use dynamic arrays with the STM
> library. Before to abandoning I want to explore all the posibilities.
> > Regarding the trick with the prepended length storing, it can solve the
> > problem, but it introduces pointer magic which may not be obvious for
> > the ones reading the code (including yourself a couple months later).
> > And, AFAIK, you won't be able to override the standard new and delete
> > operators to behave that way, so you'll have to use dedicated functions
> > to allocate/deallocate such arrays. Therefore I wouldn't recommend it
> > unless there are significant reasons for it.
> No, I don't want to overload the standard new and delete operators, just
> provide a mixing helping the user to define transactional objects. For
> these transactional objects, the overload of the operator new and new[]
> could set some information that will allow us to define a free function
> size taking a transactional object pointer and returning its size. The
> drawback of using specific functions is that we will need to educate the
> user, and yet more important, we couldn't use generic classes that make
> use of these standard operators, as e.g. auto_ptr or scoped_ptr.
> The problem I find overloading new[] is that I dont know where my prefixed
> information will be placed respect to the returned pointer, as the
> standard, prefix it already to store its own specific information.
> pointer returned by new[]
> |
> v
> | my_prefic | std prefix | user area |
> The parameter size_t of the new[] operator is the addition of sizes of std
> prefix and the user area.
> While writing these lines, I think that maybe the size of std prefix can
> be calculated requesting the creation of an array with only one element,
> so we can calculate the
> sizeof(std prefix) = requested size for new T[1] - sizeof(T)
> Does this make sens? Would this be portable?

Somehow, you need to guarantee that the memory address of the start of the
memory area is aligned properly for objects of type T, otherwise all of the
elements in the array will be misaligned. Different architectures often
have different alignment requirements.

Also, consider the following:
        T v[3];
        T* p=&v[0];
        int s = size(p); // undefined behavior

Boost list run by bdawes at, gregod at, cpdaniel at, john at