iterate char** why does this work? - c++

I picked up a this piece of code I copy past to my program. This seems to be a new way to me to iterate through char**:
char** vArray; // The array containing values
// Go throught properties
if(szKey == "KeyMgmt")
{
vArray = (char**)g_value_get_boxed((GValue*)value);
for( ; vArray && *vArray ; vArray++) // Why does this work ?!
pWpaKey->addKeyMgmt(std::string(*vArray));
}
else if(szKey == "Pairwise")
{
// ...
}
It looks like to work like a charm but I don't understant why! vArray is Supposed to contain an adress right? And *vArray the "string" value. So why when I "AND" an address with its value this give me an equality?

vArray && *vArray is equivalent to (vArray != NULL) && (*vArray != NULL)
It's first checking that the pointer vArray isn't NULL and, assuming it is not NULL, checking that the pointer it points to isn't NULL.

The loop condition is
vArray && *vArray
This is basically shorthand for
(vArray != 0) && (*vArray != 0)
which is true if the char** pointer is non-null and points to a char* which is non-null.

Related

Creating new objects for every NULL index of an object pointer array

I am trying to write a simple function that fills an array of object pointers by detecting NULL indexes and creating new objects.
Wire *wireArray[MAX_WIRES];//The array is of class "Wire" and returns a pointer to a wire object.
Wire *getWirePtrFromWireNum(int num); //the function gets the index to the array and returns a NULL if empty and the pointer if it is not NULL.
In the following if-statement, I tried to pass the index to the function and create a new Wire object if the array at that number is NULL.
if (getWirePtrFromWireNum(wirenum) == NULL) {
Wire newWire;
wireArray[wirenum] = &newWire;
}
The function for the getWirePtrFromWireNum simply checks for the NULL index and returns the pointer if it is occupied.
Wire * Circuit::getWirePtrFromWireNum(int num)
{
if (wireArray[num] == NULL) {
return NULL;
}
else {
return wireArray[num];
}
}
When I test it with a several inputs, it does not enter first if-statement at all. I did not feel the need to initialize the pointer array to NULL, but I feel like it should still be catching that the first indexes should be empty. The code does not return any errors, but the function does not seem to be doing what it should be. Where could my error be coming from?
EDIT:
for (int i = 0; i < MAX_WIRE; i++) {
wireArray[i] == NULL;
}
Fixed Function:
Wire * Circuit::getWirePtrFromWireNum(int num)
{
if (wireArray[num] == NULL) {
wireArray[num] = new Wire;
return wireArray[num];
}
return wireArray[num];
}
if (wireArray[num] == NULL) {
return NULL;
}
else {
return wireArray[num];
}
These statements don't do what you think that they do. You check wireArray == NULL, but it isn't set to NULL by default. In fact, the entire check is redundant because it can be simplified to return wireArray[num]. You need to initialize all of the elements in the array to NULL; their default values are whatever bits were left over from when the memory location was last used and are not defined.
if (getWirePtrFromWireNum(wirenum) == NULL) {
Wire newWire;
wireArray[wirenum] = &newWire;
}
You have a dangling pointer here. newWire is destroyed after the if statement.

Make c++ interpret a pointer to NULL as zero

I have this kind of code
two->height = max(two->right->height, two->left->height);
One of the two->right or two->left can be a pointer to null so the program will seg fault . I am looking for , if the two->left is null it will get transformed into zero so the two->right will be automatically true .
Is there any trick that can overcome this issue ?
This can also work:
two->height = max(
( two->right != nullptr ? two->right->height : 0 ),
( two->left != nullptr ? two->left->height : 0 )
);
You are first going to want to perform a check on the left and right pointers and see if they are null. Something along the lines of:
if(two->right == NULL) {
...
}
else if(two->left == NULL) {
...
}
else {
two->height = max(two->right->height, two->left->height);
}
There are many ways to deal with pointers being NULL. I just picked a simple one for an example.

Unexplained Behavior with std::vector

In Stepping through some weird segmentation fault causing code, I found that after the assignment of one vector to another, the receiving vector arbitrarily corrupts. The following is a code snippet from a copy constructor of a class which has a data member vector<Piece> *pieces which is a dynamically allocated array containing vectors of type Piece.
ClassName::ClassName(const Class &other) // copy constructor of class
{
...
for(SIDE_t s = 0; s < sides; s++)
{
pieces[s].reserve(other.pieces[s].size());
pieces[s] = other.pieces[s]; //vector is completely valid here
for(Uint8 p = 0; p < pieces[s].size(); p++)
{
//it continues validity throughout loop
if(other.pieces[s][p].getCell() != NULL)
pieces[s][p].setCell(cells + (other.pieces[s][p].getCell() - other.cells));
if(pieces[s][p].getCell() == NULL)
out.push_back(&pieces[s][p]);
}
if(other.flags[s] != NULL)
flags[s] = getPiece(other.flags[s]->getValue(), other.flags[s]->getSide());
// vector is invalid in scope of getPiece, which receives completely valid arguments
else
flags[s] = NULL;
}
}
Piece * const ClassName::getPiece(const Uint8 num, const SIDE_t s) const
{
return (num>nPieces || s>sides || num == 0)? NULL:&pieces[s][num-1];
// Right here during the member access function of pieces,
// it is clear that the vector was corrupted some how
}
Essentially during debugging, I would step into pieces[s] member access function. In the loop body, it is evident that m_start has a valid address, however when it exits the loop body and calls the index operator on pieces[s] in getPiece, m_start is NULL. There are no operations performed on pieces[s] between the last iteration of the loop when m_start is valid, and in getPiece when during the same call of the index operator as in the loop body, m_start is NULL. Any insight on my misuse of std::vector or bugs in std::vector would be appreciated.
It looks to me that you have an access violation here:
return (num>nPieces || s>sides || num == 0)? NULL:&pieces[s][num-1];
First (as pointed out by Petr), it should read s>=sides.
Second, s here is not the same as s in the caller. So pieces[s] may not have been assigned yet and is an empty vector. To test it use
return (num>nPieces || s>=sides || num == 0)? NULL : &(pieces[s].at(num-1));
Btw, all this would have been avoided had you simply used
std::vector<std::vector<Piece>>
and copied the whole thing.

Correct use of Syntax in if statement using && Operator and 2 variables

I have a quick question regarding proper use of syntax, basically i am trying to summarise these two if statements into one if statement.
if (sc.LastCallToFunction) {
if (p_LowRectanglesList != NULL) {
free(p_LowRectanglesList);
sc.PersistVars->i1 = 0;
}
if (p_HighRectanglesList != NULL) {
free(p_HighRectanglesList);
sc.PersistVars->i2 = 0;
}
return;
Would it be syntactically correct to rewrite this as:
if (sc.LastCallToFunction) {
if (p_LowRectanglesList || p_HighrectangleList != NULL) {
free(p_LowRectanglesList && p_HighRectanglesList);
sc.PersistVars->i1 && sc.PersistVars->i2 = 0;
}
return;
Or would the compiler not accept this / Is my Logic faulty?
you can't do it the way you have given
if (p_LowRectanglesList || p_HighrectangleList != NULL)
this logically ORs the first pointer ( treats it as true or false ) with the comparison of the seond pointer to NULL
free(p_LowRectanglesList && p_HighRectanglesList);
this logically &&s the pointers together and then tries to free the result of that operation. ie, you are trying to free "true" or "false"
sc.PersistVars->i1 && sc.PersistVars->i2 = 0;
this logically ands the two things together, which will result in true or false and then trys to assign 0 to it..... doesn't make any sense at all.
Also, in your original code....after the free, you should put p_LowRectanglesList=NULL;

testing for valid pointer in c++

I wrote a little test to check for null pointer, I simplified it with int and 0, 1, instead of real classes, what I'm trying to test is something like this: return p ? 1 : 0;
which in real world would be return p ? p->callmethod() : 0;
bool TestTrueFalse();
void main()
{
int i = TestTrueFalse();
}
bool TestTrueFalse()
{
int one = 1;
int * p =&one;
*p = 0;
return p ? 1 : 0;
}
now, you can see, that once the pointer becomes 0 again, the test fails, why?
what's wrong with this? what's the solution?
*p = 0;
you probably meant
p = 0;
*p = 0 sets what the pointer points to, not the pointer
When testing a pointer value with a conditional in C++, it will return true if the value is non-zero and false if the value is 0. In your sample p is slated to point at the local one and hence has a non-zero address (even though the value at the address is 0). Hence you get true
A null pointer is a pointer which points to the address 0, not the value 0.
To set a pointer to null, do:
p = 0;
To elaborate, your code sets the pointed-to-int to 0. For example:
int i = 1;
int *p = &i;
assert(*p == 1); //p points to 1
*p = 0;
assert(*p == 0 && i == 0); //p points to the same location, but that location now contains 0
The code *p = 0; does not set the pointer to null. It sets what p is pointing to zero.
A pointer is an address in memory. int *p = &one; takes the address of the variable one, and stores it in p. *p = 0; stores 0 in the memory pointed to by p, meaning that the value of one is now 0. So, you have changed what p points to, but not p itself. TestTrueFalse() will return 1.
to test it for a null pointer before inspecting the value pointed to you might use code like
if(ip != NULL)
taken from http://www.eskimo.com/~scs/cclass/notes/sx10d.html
NULL might be safer in your code, as it is more compiler independent than just writing 0. and it might also be more clear for others to read in your code.