20

for debug purposes I often output pointer values (mostly this) to qDebug:

qDebug("pointer of current object = 0x%08x",this);, using "%08x" as format string and simply passing this as a parameter.

How can I convert the pointer value to a QString?

This is what I got so far:

char p = (char)this;
return QString("0x%1").arg(p, 8, '0');

But the compiler doesn't seem to figure out what to do with that value. Is casting to char correct in this case? Or what would be a safer way to do this?

Using Visual C++ with Qt 4.7.4.

EDIT

Using qulonglong as suggested

qulonglong p = (qulonglong)this;
return QString("0x%1").arg(p, 8, '0');

yields in a compiler error message (error C2666).

Martin Hennings
  • 16,418
  • 9
  • 48
  • 68
  • Converting the pointer to a char will produce wrong result, as characters are only eight bits. Try `qulonglong` instead (or `qulong` if you are on a 32-bit system). – Some programmer dude Jan 16 '12 at 15:17
  • What do you think `qDebug` is doing when you pass `this` as a parameter with the format specifier in that literal string? – AJG85 Jan 16 '12 at 15:23
  • Sincerely: I have not much of a clue. I know that "%08x" represents an 8-bit hexadecimal value. – Martin Hennings Jan 16 '12 at 15:26
  • In the format string `"%08x"`, the "8" doesn't mean it's 8 bits, it means that the width will be 8 characters. The "0" means that if the value is not enough for 8 characters, it will be padded with the character '0'. I suggest you read more about `printf` and its formatting. – Some programmer dude Jan 16 '12 at 15:46
  • Thanks for that hint. The "x" actually makes the output hexadecimal. The "8 bit" remark was nonsense, sorry. "%08x" will output the number as zero-padded, 8-digit hex number, which represents 32 bit. So I guess for an x64 pointer this would read "%016x"? – Martin Hennings Jan 16 '12 at 15:56
  • Prefer C++ casts over c-style casts: `static_cast(this)` etc. – AJG85 Jan 16 '12 at 16:06
  • 1
    Better use: `qDebug("pointer of current object = %p", this);` or `qDebug() << "current object = " << this;` – quinmars Jan 17 '12 at 00:24

5 Answers5

25

Using QString::arg():

MyClass *ptr = new MyClass();
QString ptrStr = QString( "0x%1" ).arg( reinterpret_cast<quintptr>(ptr), 
                    QT_POINTER_SIZE * 2, 16, QChar('0') );

It will use the correct type and size for pointers (quintptr and QT_POINTER_SIZE) and will always prefix "0x".

Notes:
To prefix the value with zeros, the fourth parameter needs to be QChar('0').
To output the correct number of digits, QT_POINTER_SIZE needs to be doubled (because each byte needs 2 hex digits).

Ignitor
  • 2,907
  • 33
  • 50
14

Why not simply use QString & QString::sprintf ( const char * cformat, ... )

QString t;
// QString::sprintf adds 0x prefix
t.sprintf("%08p", ptr);
Kamil Klimek
  • 12,884
  • 2
  • 43
  • 58
8

QTextStream appears to offer the functionality you seek, and operates simply on a void*.

const void * address = static_cast<const void*>(ptr);
QString addressString;
QTextStream addressStream (&addressString);
addressStream << address;
qDebug() << addressString;

Unlike the other approaches, it does not reference notions like the particular number "8" or casting to "qlonglong". Seems less worrisome, and is much like the prescribed method for std::string (though without getting std::string conversions involved)

Community
  • 1
  • 1
2

You could do an intermediate step with sprintf:

QString pointer_to_qstring(void *ptr)
{
    char temp[16];
    sprintf(temp, "0x%08p", ptr);
    return QString(static_cast<char *>(temp));
}

Or through ostringstream:

QString pointer_to_qstring(void *ptr)
{
    std::ostringstream oss;
    oss << std::setw(8) << std::setfill('0') << std::hex << ptr:
    return QString(oss.str().c_str());
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

For me mostly it is enough to see if the pointer is the nullptror if it has the same value as an other pointer. For those cases it is enough to convert the pointer to a number and then use QString::number()

Cat * cat = new Cat();
qDebug()<<QString::number((std::uintptr_t)(cat));;
newandlost
  • 935
  • 2
  • 10
  • 21
  • Your answer's output isn't hexadecimal (use argument 16 in `QString::number()`), not starting with `0x` and not zero-padded (use `QString("0x%1").arg(pointer, length, 16, QChar('0'))`, as in @Ignitor s answer). – Martin Hennings Nov 09 '17 at 09:41
  • (I agree that using padded hexadecimal output is not neccessary to compare pointer values. But in hex comparing is easier because the strings are shorter. And my debugger (VS2012) always displays addresses in hex.) – Martin Hennings Nov 09 '17 at 09:44
  • That is what I am saying. For me it is not important to get in hex format and I wonder if the one that asked that questions needs the hex format at all. – newandlost Nov 09 '17 at 09:44