C++ Coding: const char * data type
coding cpp stringliterals
What does const char * mean?
Been having some issue with IoT Hub connectivity data. In Azure IoT SDK C examples and in some previous coding, have always hardcoded such data using #define string literals. For example:
#define IOTHUBNAME ="My_Hub.azure-devices.net"
// In Globals:
const char * IoTHub = IOTHUBNAME;
At runtime, it can be overridden by user input.
In the current Arduino context Softata Arduino Sketch I wanted to store that information in flash and read it back in from there at startup, giving it persistence. That mechanism works where it is stored and read back in and the .c_str()
method is applied to get the const char *
version. I found that when the stored data is read back in it gets corrupted. Here is why and the solution. The flash read is in a separate function to that which makes the connection to the IoT Hub.
What does const char * mean?
The data type is a pointer whose address in memory is fixed but what it points to can be changed. For example:
#define AString "AAAA"
#define BString "BBBB"
const char * var1 = AString;
const char * var 2 = BString;
var2 = var1; // Will work
The last line works as you are only changing where var2 points to, not its location. The string literals are stored in a separate segment in program memory and so are fixed. In the above you are just changing which string literal in program memory is being referenced.
var1 and var2 are only an address place holders with a designated type that they points to.
One issue to avoid is where the data pointed to goes out of context. For example:
const char * SomeData = "ABCD";
void func()
{
const char * otherData = "1234";
someData = otherData;
}
void func2()
{
func();
Serial.println(someData);//Errant
}
The problem is where data structures use const char *
in their definition. The key is to make sure that the data being consumed remains in context, for which the simple implementation is to make sure they are global.
const char * SomeData = "ABCD";
const char * otherData = "1234"; //Moved to global
void func()
{
someData = otherData;
}
void func2()
{
func();
Serial.println(someData);//Works
}
Conclusion
So with the issue presented at the start, when the String is converted to const char *
, what it is assigned to needs to be global.
See:
- https://github.com/djaus2/Soft-ata/blob/master/code/Softata/iothub.h
- initializeClients()
- tempHost = hostStr.c_str();
- tempDevice_id = device_idStr.c_str();
- See comment below that.
- These two are defined in globals but if defined within method get corruption when
az_iot_hub_client_init()
in the SDK is called.
- initializeClients()
- What is curious though is that this issue does not arise with
device_key_ConstCharStar
ingenerateSasToken()
probably because it is directly converted inbase64_decode_chars()
.
Topic | Subtopic | |
Next: > | Softata | A Quick Start with Blockly |
This Category Links | ||
Category: | Coding Index: | Coding |
Next: > | ConsoleTextFormat | Formatting Console App Text |
< Prev: | App Settings for a .NET Console App | Save, Retrieve and Validate IPAddress and Port |