# Strings

Symbian doesn't use the C `char *` strings but provides classes that does range checking called descriptors. (an overflow in a `char str[n]` string is probably the most common mistake that allows an attacker to take control over a system. This is achieved by overwriting the stack frame. So it's nice that Symbian libraries does all the range checking).

There are several classes of the desctiptors. The `TDesC` is an abstract class which is an ancestor of constant strings. The `TDes` is a subclass `TDesC` and adds some functions to modify strings - it is an ancestor of all the modifiable strings. A `TBuf<n>` is a class that keeps n characters as a part of itself (thrus the T prefix). It is usually used to keep some temporary strings as automatic variables. However because of the small stack in Symbian devices you should not keep too many string on the stack.

`TPtrC` objects stores a pointer to a constant buffer which it doesn't own and the information about it's length. E.g. a `TPtrC` can point to characters 5 to 10 of a `TBuf<64>`. Destroying the `TPtrC` will not hurt the data in the `TBuf`. However if you destory the `TBuf`, the `TPtrC` will become invalid. A `TPtr` is a modifiable version of `TPtrC` (i.e. you can modify the data in the buffer).

If you want to keep the string on the heap use a `HBufC`. The `HBufC` objects cannot be kept on the stack but must be created on the heap like C classes but on the other hand it also doesn't need a virtual destructor as all the data is inlined like in T classes. That's why is has a special prefix - H. As the C suffix suggests that class is non-modifiable directly but there is a `Des()` function which returns a `TPtr` to the data, which will allow you to modify the content.

Symbian also needs to introduce it's own way to handle string literals (i.e. which are hard-coded in the source code). There is a macro `_LIT`. For example `_LIT(a, "Text")` will declare the constant `a` as a `TDesC`-derived object (more exactly of type `TLit`) with the content "Text". It can be used both to declare global constants as well as literals inside functions:

    _LIT(KFormat, "String: %S");

    void Function()
    {
        TBuf<64> buffer;
        _LIT(tmp, "ABC");
        buffer.Format(KFormat, &tmp);
        /* ... */
    }

(this code will generate "String: ABC"). There is also a `_L` macro which has one parameter and is used like this: `buffer.Format(_L("Count: %d"), 17);` however it is discouraged as it generate worse code.