2

Is there a way to detect if objects pointed by p and d are of different types? (p points to int and d points to array of ints):

int* p = new int();
int* d = new int[20];  
smallB
  • 16,662
  • 33
  • 107
  • 151
  • Why do you want to detect it? There is no way this can be done. – Alok Save Jan 30 '12 at 17:44
  • Yes, by the square brackets after the declaration (OK, that was a stupid comment) – Jakub M. Jan 30 '12 at 17:46
  • This is not exactly what you are asking about, but it's related. The compiler might for optimization purposes keep track of similarly detailed type info. http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule – Prof. Falken Jan 30 '12 at 17:52

4 Answers4

6

...objects pointed by p and d are of different types? (p points to int and d points to array of ints):

Well, first off, that's not really correct. Yes, d points to the beginning of an array, but they both point to the exact same thing; an int. Whether or not you can safely perform arithmetic on the pointer and then dereference it is another question.

When you dereference them the machine simply gives you back an appropriately sized chunk of memory and interprets it as an int.

C++ isn't exactly the goto language for meta programming, and if you're dealing with pointers does it really matter anyway? I've never found the need to do this. You know you have a pointer, you (should) know if it points to one int or a bunch of ints as you declared it, so what exactly is the problem you are trying to solve?

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • #Ed "the problem" is that I'd like to be able to write delete_(p) and depending on "type" of p it would invoke delete p or delete[] p; – smallB Jan 31 '12 at 17:33
  • @smallB: You just need to know what you allocated to begin with. Why is this difficult? Instead of asking for a solution that doesn't make any sense, just tell us what problem you are actually trying to solve. I have never needed to determine *at runtime* which version of `delete` to call. – Ed S. Jan 31 '12 at 17:36
  • #Ed I didn't say anywere that I need to detect it in runtime. I just wanted to have "smart" delete, that would save me from checking what am I deleting, an array or not. That's it. Does it make more sense now? – smallB Jan 31 '12 at 17:40
  • @smallB: Not really. I mean, I can see your point, but the problem is that **this is impossible**. The language designers would not have created two versions if one would have been sufficient. – Ed S. Jan 31 '12 at 18:56
0

I would say that no. both p and d are pointers to int, d is a pointer to the head of the array - and the head is an int.

array of ints is not the type of d - it's a pointer to int

Belgi
  • 14,542
  • 22
  • 58
  • 68
-1
#include <iostream>
#include <typeinfo>

using namespace std;

int main()
{
    int* p = new int();
    int* d = new int[20];
    float* f = new float();

    if (typeid(p) == typeid(d))
            cout << "equal" << endl;
    else
            cout << "not equal" << endl;

    if (typeid(p) == typeid(f))
            cout << "equal" << endl;
    else
            cout << "not equal" << endl;

}

Outputs:

equal
not equal

Is there a way to detect if objects pointed by p and d are of different types?

Your supposition is false. p and q are both pointing to the same type, an int.

Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319
  • -1 They are both pointers to int... Even `typeid(*p)` (and same for `q`) will just be `int`. – Ed S. Jan 30 '12 at 17:48
  • *Yes you can, but your example is pointing at the same type.* - So the answer is... no, you cannot. – Ed S. Jan 30 '12 at 17:54
-1

If you implement your own new and new[] you could, but the dragons here will eat you alive:

void * operator new(size_t size)
{
    size_t * allocation = (size_t *)malloc(size+sizeof(size_t));
    *allocation = size;
    return allocation + 1;
}

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

template<typename T> size_t allocationCount(T*memory)
{
    size_t * allocation = reinterpret_cast<size_t*>(memory) - 1;
    return *allocation / sizeof(T);
}

int main()
{
    int * fred = new int;
    int * nurk = new int[30];
    cout << allocationCount(fred) << endl;
    cout << allocationCount(nurk) << endl;
}

Outputs:

1
30
Slagh
  • 342
  • 2
  • 8
  • Ugh! Really? Such an impossibly inadequate and unusable approach. Did you consider `new int[1]`? Once you've taken care of that issue you can move on to the other few dozen you'll face trying to get this to work. – Captain Obvlious Jan 30 '12 at 19:24