C++ Null Test After Dereference - c++

I have the below c++ code
*dtcStatus = DataDTC[idxDTC].status;
if (dtcStatus != NULL) {
return E_OK;
} else {
ALOGE("Dem_GetStatusOfDTC return NULL");
return E_NOT_OK;
}
My static analysis tool is reporting warning for the above code Null Test After Dereference

My static analysis tool is reporting warning for the above code Null Test After Dereference
This is where you indirect (dereference) through the pointer:
*dtcStatus = DataDTC[idxDTC].status;
This is where you test for null:
if (dtcStatus != NULL) {
If look closely, you'll notice that the indirection is before the check. If the program would enter the else branch, then it must have indirected through a null pointer and thus the behaviour of the program is undefined. This is why the tool informs you of this bug.
Any way to over come that
You can over come "testing for null after dereference" by not doing that. In other words, by testing for null before the indirection. Simply swap those two lines.

This line
*dtcStatus = DataDTC[idxDTC].status;
is dereferencing dtcStatus (via the * operator). You are only allowed to do that when you are absolutely certain that dtcStatus is a valid pointer, ie points to some instance, ie is not NULL.
Now the static analyzer tries to tell you that either
you are absolutely certain that the pointer is valid. In that case you do not have to check whether it is NULL on the next line. Or...
you are not certain. In this case you should check for NULL before you dereference the pointer.

The compiler is actually telling you what's wrong
Null Test After Dereference
Means you are trying to test a variable with NULL after dereferencing it.
You should rather not dereference your variable for the NULL check:
if (DataDTC[idxDTC].status != NULL) {}
Or if you want still want to use your variable you could test &dtcStatus.

Remove the star at the beginning here:
*dtcStatus = DataDTC[idxDTC].status;

Related

Testing against NULL or nullptr

See this code:
if (m_hStatusBarPageBreakIcon != NULL)
VERIFY(DestroyIcon(m_hStatusBarPageBreakIcon));
Sometimes when I have opted to use nullptr the compiler complains. But as a general rule is it OK to use nullptr? This variable is of type HICON.
Assuming compiler supports nullptr, the only case where checking a handle for NULL works, but for nullptr fails to compiler is a case where a handle is not defined as a pointer.
As Windows headers define NULL as 0, the check for NULL could work for integer handles, for example. Sure checking an integer for nullptr is an error.
For such cases, if some handle is integer, or some API is documented to accept NULL, I would still replace NULL, not with nullptr, but with literal 0.
I will look on that from a different perspective. Basically I want to have typesafe code.
NULL is even better than nullptr, because 0 is of type int and nullptr is anything.
And static code analysis tools will emit an information if you write uint i=3U, then some more code and then if (i == 0). Same with NULL and nullptr.
So, what I use is:
template <typename T>
const T null(void)
{
return static_cast<T>(0);
}
Example code
typedef unsigned char uchar;
. . .
uchar someVariable = null<uchar>();
SomeComplexClass *someComplexClass = null<SomeComplexClass *>();
. . .
if (null<SomeComplexClass *>() == someComplexClass)
{
. . .
}
The normal programmer will sit there and say. What is that nonsense?
But consider, we develop some ASIL D code. And then you refactor your code. And you will accidently modify "SomeComplexClass" to "someOtherComplexClass".
if (null<SomeComplexClass *>() == someOtherComplexClass)
With this typesafe 0, the static code analysis tools will emit an info.
Think of that, when you drive your car next time with an ASIL D rated steering-wheel, brake- or accelarator-pedal software.
BTW: also auto should be avoided wherever possible in such code.

Method to set a char array equal to each other wont work

For my homework assignment I am required to use pointers to navigate arrays in c++. The set function I have written to set a private object member variable char m_make[] equal to the passed char[] is not functioning correctly. When I try and run my program it appears to terminate after I call the setMake() function. What am I doing wrong?
Function declaration: (contained in an object called RentalCar)
void setMake(char make[5]);
Here is the code for setMake():
void RentalCar::setMake(char make[5]){
for(int i = 0; (make+i) != '\0';i++){
*(m_make+i) = *(make+i);
}
}
When I call setMake() no matter what I pass the function the output is Process returned followed by a very large number.
In your for loop, you are checking (make+i) != '\0' which basically adds i to make each time you iterate. make is the memory address of the first character of the array.
With that being said, (make+i) will never be == '\0' because (make+i) is a memory address, and addresses that your program has access to are never NULL which means it is an infinite loop.
You need to use the pointer notation to actually de-reference your (make+i) so that it checks the value that is inside the memory (make+i) but not the address itself. Means, you have to do:
*(make + i) != '\0'
to get the value and compare it, just like you are doing to set the value:
*(m_make+i) = *(make+i);

Can you use strcmp() to check for nullptr value?

Is this piece of code any good to check if a pointer or variable hold a nullptr value?
if(strcmp(variable/pointer, nullptr) == 0){
Do something cool
}
I'm trying to work on some code and I want to know the best way to check if there is a nullptr value present.
Thanks.
I think what you want is
if (!pointer || !variable) {
// do something cool
}
!pointer is essentially the same thing as pointer == nullptr and is considered by some to be better style. See Can I use if (pointer) instead of if (pointer != NULL)?
strcmp is meant to be for C string comparisons. https://www.tutorialspoint.com/c_standard_library/c_function_strcmp.htm
You cannot use strcmp to check whether a variable is equal to nullptr. From strcmp documentation:
Parameters
lhs, rhs - pointers to the null-terminated byte strings to compare
Not only do the input arguments to strcmp need to point to byte strings, they must point to null-terminated byte strings.
Besides, you are making things may more complex than they need to be. You can just use:
if ( variable != nullptr )
{
// Do something
}
else
{
// Do something else
}
strcmp() has undefined behaviour if either argument is a null pointer. Therefore it is necessary to check for null before calling strcmp().
For example, to only call strcmp() if both intended arguments are not null
if (first && second && !strcmp(first, second))
{
// first and second are both non-null, and contain matching strings
}
or (more verbosely, C++11 and later)
if (first != nullptr && second != nullptr && strcmp(first, second) == 0)
{
// first and second are both non-null, and contain matching strings
}
In C++, you'd be better off using the std::string type, rather than messing around with arrays of char, string termination, and functions like strcmp().

sprintf_s() fails with "debug assertion failed" error

The problem is probably something simple, but I couldn't get it to work after hours of research and editing, so here I post my issue.
I am trying to make a function which receives either a single digit integer or a two digit integer and returns it as a string after converting it to a two integer format (e.g. 7 to 07).
char *to_two_digits(int num) {
char num_str[4];
sprintf(num_str, "%d", num);
int length = sizeof(*num_str) / sizeof(char);
static char *return_string;
if (length == 1) {
sprintf_s(return_string, "0%d", num);
return return_string;
}
else if (length == 2) {
*return_string = *num_str;
return return_string;
}
else {
printf("Error! Number cannot be represented as a two-digit.");
exit(1);
}
}
The function fails when the sprintf_s() function is run, with an error that says:
--------------------------- Microsoft Visual C++ Runtime Library-----------
Debug Assertion Failed!
File: minkernel\crts\ucrt\src\appcrt\stdio\output.cpp
Line: 261
Expression: format != nullptr
What is the problem, and how can I fix it? Thank you in advance.
You are passing a null pointer to the sprintf_s function. The pointer that you declare in this line
static char *return_string;
was never initialized to point to anything. Since it is declared static, it is pre-initialized to zero (rather than just having an indeterminate value).
This is what the message is telling you. There is an assert in the sprintf_s code that checks that you have not passed a null pointer, and that is what is firing.
You are supposed to pass in a pointer to a buffer that the function can write into. But since you are using C++, you're really just supposed to use a std::string for this, which you could then return from the function without needing a static variable.
It's exactly what it says — you're passing a null pointer to sprintf_s.
It's that return_string, which you did not initialise to point to anything, let alone a buffer of sufficient size for the actual result. Rather than being of indeterminate value, it is assuredly a null pointer by virtue of being static, but this assurance doesn't help you.
It's actually not a good idea to use static for memory management like this, because your function is 100% non-re-entrant. Usually you'd have your users pass in a buffer of sufficient size for the result, and let that calling scope handle the buffer's lifetime.

null pointer in C++

everyone, I have some question about C++, what do You actually prefer to use
int* var = 0;
if(!var)...//1)
or
if(var == 0)..//2)
what are the pros and cons? thanks in advance
I prefer if (!var), because then you cannot accidentally assign to var, and you do not have to pick between 0 and NULL.
I've always been taught to use if (!var), and it seems that all the idiomatic C(++) I've ever read follows this. This has a few nice semantics:
There's no accidental assignment
You're testing the existence of something (ie. if it's NULL). Hence, you can read the statement as "If var does not exist" or "If var is not set"
Maps closely to what you'd idiomatically write if var was a boolean (bools aren't available in C, but people still mimic their use)
Similar to the previous point, it maps closely to predicate function calls, ie. if (!isEmpty(nodeptr)) { .. }
Mostly personal preference. Some will advise that the first is preferred because it becomes impossible to accidentally assign instead of compare. But by that same token, if you make a habit of putting the rvalue on the left of the comparison, the compiler will catch you when you blow it:
if( 0 == var )
...which is certainly true. I simply find if( !var ) to be a little more expressive, and less typing.
They will both evaluate the same, so there's no runtime difference. The most important thing is that you pick one and stick with it. Don't mix one with the other.
Either one is good, though I personally prefer 2 - or something like it.
Makes more sense to me to read:
if ( ptr != NULL )
than
if ( ptr )
The second I may confuse for just being a boolean to look at, but the first I'd be able to tell immediately that it's a pointer.
Either way, I think it's important to pick one and stick with that for consistency, though - rather than having it done in different ways throughout your product.
A few years has passed...
The C++11 standard introduced nullptr to check for null pointers and it should be used as it ensure that the comparison is actually done on a pointer.
So the most robust check would be to do:
if(myPtr != nullptr)
The problem with !var is that it's valid if var is a boolean or a numerical values (int, byte etc...) it will test if they are equal 0 or not.
While if you use nullptr, you are sure that you are checking a pointer not any other type:
For example:
int valA = 0;
int *ptrA = &valA;
if(!valA) // No compile error
if(!*ptrA) // No compile error
if(!ptrA) // No compile error
if(valA != nullptr) // Compile error, valA is not a pointer
if(*ptrA != nullptr) // Compile error, *ptrA is not a pointer
if(ptrA != nullptr) // No compile error
So, it's pretty easy to make a mistake when manipulating pointer to an int as in your example, that's why nullptr should be used.
I would prefer option 3:
if(not var)
{
}
The new (well since 1998) operator keywords for C++ can make code easier to read sometimes.
Strangely enough, they seem to be very unknown. There seem to be more people who know what trigraphs are (thank you IOCCC!), than people who know what operator keywords are. Operator keywords have a similar reason to exist: they allow to program in C++ even if the keyboard does not provide all ANSII characters. But in contradiction to trigraphs, operator keywords make code more readable instead of obfuscating it.
DON'T use NULL, use 0.
Strictly speaking, pointer is not bool, so use '==' and '!=' operators.
NEVER use 'if ( ptr == 0 )', use 'if ( 0 == ptr )' instead.
DON'T use C-pointers, use smart_ptr instead. :-)
According to the High Integrity C++ coding Standard Manual: for comparison between constants and variables you should put the constant on the left side to prevent an assignment instead of an equality comparison, for example:
Avoid:
if(var == 10) {...}
Prefer
if(10 == var) {...}
Particularly in your case I prefer if(0 == var) because it is clear that you are comparing the pointer to be null (0). Because the ! operator can be overloaded then it could have other meanings depending on what your pointer is pointing to: if( !(*var) ) {...}.