From: James Kanze on
On Apr 1, 3:04 pm, Goran <goran.pu...(a)gmail.com> wrote:
> On Mar 31, 9:39 pm, pfultz2 <pful...(a)yahoo.com> wrote:

> There is NO "neater way" but to KNOW, at any point in your
> code, what you need to do with any object/variable.

Note that in practice, most types will either be always
allocated dynamically, or never allocated dynamically. There
are exceptions, but they aren't that frequent.

--
James Kanze

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
On Mar 31, 8:39 pm, pfultz2 <pful...(a)yahoo.com> wrote:
> I want detect if a pointer is pointing to memory on the heap
> or the stack, so I came up with this approach:

> bool isOnHeap(void * p)
> {
> int i = 0;
> int * s = &i;
> return (p > s);
> }

> I dont if this is the best or most portable way to do it.

It's not at all portable. It will work under Solaris on Sparc
and Linux on PC (and probably Solaris on PC and Linux on Sparc).
I don't think it will work for Windows, however, and it
definitely will not work on HP/UX on PA.

And of course, it will only work in a single threaded program.

> And im not sure how well it works for static and global
> variables, do they start on the end of memory? or at the
> begining?

Yes:-).

There are no absolute rules. On machines where the hardware
stack grows down (Intel, Sparc), most Unix systems will arrange
the memory more or less like:

+-------+
| stack |
+-------+ <--- stack pointer
| free |
+-------+
| heap |
+-------+ <--- end
| bss |
+-------+
| data |
+-------+
| text |
+-------+

With the data at the bottom, and a predefined symbol end at the
top of the static variables. (Bss is the traditional name for
static objects with no specified initialization: "data" gets
copied from disk when the program is loaded, and "bss" gets set
to 0.)

But there's certainly nothing which guarantees this layout; it's
probably more of a historical tradition than anything else.

> The reason why i want to do this is need to delete pointers
> sometimes, and some of them point to memory on the stack, so
> therefore i dont want to delete them,

The correct solution here is to use dynamic allocate
systematically in cases where dynamic allocation might make
sense, and to never take the address of an object. The unary &
operator is something you should almost never use.

--
James Kanze

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
On Apr 2, 5:02 pm, Mark Zaytsev <mark.zayt...(a)gmail.com> wrote:
> On Apr 1, 10:03 am, George Neuner <gneun...(a)comcast.net> wrote:

> > On Wed, 31 Mar 2010 13:39:59 CST, pfultz2
> > <pful...(a)yahoo.com> wrote:
> > >I want detect if a pointer is pointing to memory on the
> > >heap or the stack, so I came up with this approach:

> [skip]

> > The stack check works on Unix/Linux and Windows because
> > their stacks are contiguous - but there may be other
> > platforms for which it won't work (although I've yet to meet
> > such a platform).

> Stack of which thread ?
> If object allocated on the other thread's stack, your check
> will say: HEAP...

Maybe, maybe not. If the function is called from another
thread, it might also say STACK, when the data is actually on
the heap.

Of course, if you're working in a multithreaded environment,
with all of the threads being started by some common function,
and no objects are ever allocated from main, it's easy to see if
an object is on the current thread's stack, some other thread's
stack, or elsewhere, since you can control the addresses of the
stacks.

--
James Kanze

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: rado on
On Mar 31, 12:39 pm, pfultz2 <pful...(a)yahoo.com> wrote:
> I want detect if a pointer is pointing to memory on the heap or the
> stack, so I came up with this approach:
>
> bool isOnHeap(void * p)
> {
> int i = 0;
> int * s = &i;
> return (p > s);
>
> }
>
> I dont if this is the best or most portable way to do it. And im not
> sure how well it works for static and global variables, do they start
> on the end of memory? or at the begining? The reason why i want to do
> this is need to delete pointers sometimes, and some of them point to
> memory on the stack, so therefore i dont want to delete them, I could
> use type erasure and create a seperate class to handle the memory and
> use some form of custom deallocators, but then it would either cost me
> an extra pointer or double dereferencing, and i was trying to think of
> a neater way to do it. thanks.

{ edits: quoted banner removed. please keep readers in mind when you quote.
thank you. -mod }

As others noted already, it is *not* possible, as per C++ standard.
You just must *know* it; just the same way that you *know* what a
function you are writing does.
Beside that, though, I was wondering whether it is possible to develop
such "address classification" facility IN PRACTICE. Here's how it can
be done:
For linear stacks (address ranges with no 'holes'), recognizing a
stack variable is trivial, by just checking if it is in the range of
the addresses. If similar property exists for addresses of global/
static objects, they can be recognized in a similar manner as well.
What remain are the heap objects. Voila!
Of course, such a facility should be better provided by the
implementation, and is doomed to be nonportable.
Now, is it good to have it though? It depends. If uses as a crutch for
sloppy designers, NO. But it might be useful for debugging/diagnostics
purposes, e.g. for signalling illegal 'delete' in better/more
predictive way.

Real world example: here's a function that I wrote:

//
==============================================================================
// Check if 'pVariable' is on the stack (of the current thread).
// Neither portable nor 100% foolproof, but works in practice.
// (The platform is Windows/MSVC.)
//
________________________________________________________________________________________
bool isOnStack (const void* pVariable)
{
char k = 0;
intptr_t nDiff = (char*) pVariable - &k;
if (nDiff < 0)
nDiff = -nDiff;
bool bRet = nDiff < 30000; // Any other not-too-big-not-too-small
magic number is good
return bRet;
}

And I just found out that I only used it once (inside assert) in a
project of several hundred thousand lines of code. This - to me -
underlines again the limited utility of such things.

-- Radoslav Getov



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: pfultz2 on
On Apr 2, 7:46 am, Goran <goran.pu...(a)gmail.com> wrote:
> On Apr 2, 9:36 am, pfultz2 <pful...(a)yahoo.com> wrote:
>
>
>
> > For example, if I have two classes like this:
> > template<class T, int N>
> > class value_array
> > {
> > T data[N];
>
> > public:
> > int length()
> > {
> > return N;
>
> > }
>
> > T* pointer()
> > {
> > return data;
>
> > }
>
> > //Methods for operator overloading
>
> > };
>
> > template<class T>
> > class array
> > {
> > int len;
> > T* data;
>
> > public:
> > explicit array(int n)
> > {
> > len = n;
> > data = new T[N];
>
> > }
>
> > template<int N>
> > array(value_array<T, N>& a)
> > {
> > data = a.pointer();
> > len = N;
>
> > }
>
> > int length()
> > {
> > return N;
>
> > }
>
> > T* pointer()
> > {
> > return data;
>
> > }
>
> > void deallocate()
> > {
> > if (is_heap(data)) delete [] data;
>
> > }
>
> > //Methods for operator overloading
>
> > };
>
> > This is kind of a rough sketch of what im trying to accomplish.
>
> Why not simply this:
>
> class array
> {
> // ...
> bool _owns;
> explicit array(int n) : _owns(true)
> {
> len = n;
> data = new T[N];
> }
>
> template<int N>
> array(value_array<T, N>& a) : _owns(false)
> {
> data = a.pointer();
> len = N;
> }
> ~array()
> { // NB: you should probably forget your "deallocate" idea.
> if (_owns) delete [] data;
> }
>
> }
>
> But! But... I seriously question your design.
>
> Why do think you should have modifiable data in multiple arrays like
> this? Do you actually want to mix them this way? From a design
> standpoint, it seems mighty dubious to me.
>
> One reason I can think of why you would want that is that after
> __serious__ performance measurement and a __serious__ work on
> optimization (most notably, elimination of copying), you still need to
> go faster.
>
> If, OTOH, you were thinking "it will be faster if I do it this way"
> for no apparent reason... Just forget the whole idea and go for
> std::vector. Honestly. Also, did you consider using shared_ptr?
>
> Goran.
>
> --
> [ Seehttp://www.gotw.ca/resources/clcm.htmfor info about ]
> [ comp.lang.c++.moderated. First time posters: Do this! ]

The problem with vector and shared_ptr, which would give the same
semantics respectively, is first they are not a POD type. Secondly, I
want to emulate the semantics that are in C, but have lenght available
also. So there are two ways to create an array in C, 1) Create one
dynamically, and use a pointer to it, or 2) Create one statically on
the stack. Now, using my design I can pass arrays by value or by
reference, like this:

void fun1(array<int> a)
{
//Process array
}

int main(int argc, char** argv)
{
value_array<int, 5> a;
fun1(a);
}

Now it works like this also, in C:
void fun1(int* a, int len)
{
//Process array
}

int main(int argc, char** argv)
{
int a[5];
fun1(a, 5);
}
But the length is carried along with it and plus I can add begin() and
end() methods to get the iterators(or rather pointers) for the array,
which is the standard methods to call on containers. This only seems
like the next logical step in C++, to use a class. The problem is when
I want to create a managed version of the array class, for
shared_array, its ok. Here is rough example:

template<class T>
class shared_array : public array<T>
{
private:
share_count sc; //Similar to whats used in boost shared_ptr
public:
template<int N>
shared_array(value_array<T, N> a)
{
data = a.pointer();
len = N;
sc = share_count(data, null_deleter());
}

explicit shared_array(int n)
{
data = new T[n];
len = n;
sc = share_count(data, array_deleter());
}

//Make the user decide for how to deallocate
template<class D>
shared_array(array<T> rhs, D deallocator)
{
data = a.pointer();
len = n;
sc = share_count(data, deallocator);
}

};

But sometimes shared_array is too much, so it would be better to have
unique_array:
template<class T>
class unique_array : public array<T>
{
template<int N>
unique_array(value_array<T, N> a)
{
data = a.pointer(); //We shouldnt delete beacause its on the
stack
len = N;
}

explicit unique_array(int n)
{
data = new T[n];//We should delte because its on the heap
len = n;
}

unique_array(array<T> rhs)
{
data = a.pointer(); //Maybe we delete or maybe not, this could
be from the heap or the stack
len = n;
}

//...create move constructors

~unique_array()
{
this->deallocate(); //How can I tell if this is on the stack or
in the heap?
}
};

However, we dont know if the array should be deallocated or not. We
could always carry a bool along with the array to know whether it is
from the stack or heap,but it has extra overhead. and i thought there
was an easy way to tell if the pointer is on the heap, or a Win32 or
POSIX command that could tell you if it was on the heap or not.
Thanks for the answers


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]