Tutorial :strlen() not working



Question:

Basically, I'm passing a pointer to a character string into my constructor, which in turn initializes its base constructor when passing the string value in. For some reason strlen() is not working, so it does not go into the right if statement. I have checked to make sure that there is a value in the variable and there is.

Here is my code, I've taken out all the irrelevant parts:

Label class contents:

Label(int row, int column, const char *s, int length = 0) : LField(row, column, length, s, false)  {  }    Label (const Label &obj) : LField(obj)\  {  }    ~Label()  {  }    Field *clone() const  {      return new Label(*this);  }  

LField class contents:

LField(int rowNumVal, int colNumVal, int widthVal, const char *valVal = "", bool canEditVal = true)  {       if(strlen(valVal) > 0)      {      }      else      {          //This is where it jumps to, even though the value in          //valVal is 'SFields:'          val = NULL;      }  }    Field *clone() const  {      return new LField(*this);  }    LField(const LField &clone) {       delete[] val;      val = new char[strlen(clone.val) + 1];       strcpy(val, clone.val);      rowNum = clone.rowNum;      colNum = clone.colNum;      width = clone.width;      canEdit = clone.canEdit;      index = clone.index;  }  

Screen class contents:

class Screen {      Field *fields[50];      int numOfFields;      int currentField;  public:      Screen()      {          numOfFields = 0;          currentField = 0;          for(int i = 0; i < 50; i++)          fields[i] = NULL;      }          ~Screen()      {           for (int i = 0; i < 50; i++)              delete[] fields[i];       }        int add(const Field &obj)      {          int returnVal = 0;          if (currentField < 50)          {              delete[] fields[currentField];              fields[currentField] = obj.clone();                 numOfFields += 1;                 currentField += 1;                    returnVal = numOfFields;              }          return returnVal;      }        Screen& operator+=(const Field &obj)      {          int temp = 0;          temp = add(obj);          return *this;      }  };  

Main:

int main () {      Screen s1;      s1 += Label(3, 3, "SFields:");  }  

Hopefully someone is able to see if I am doing something wrong.


Solution:1

Marcin at this point the problem will come down to debugging, I copied your code with some minor omissions and got the correct result.

Now it needs to be said, you should be using more C++ idiomatic code. For instance you should be using std::string instead of const char* and std::vector instead of your raw arrays.

Here is an example of what the LField constructor would look like with std::string:

#include <string> // header for string      LField(int rowNumVal,            int colNumVal,            int widthVal,            const std::string& valVal = "",            bool canEditVal = true)    {      std::cout << valVal;        if(valVal.length() > 0)        {        }        else        {            //This is where it jumps to, even though the value in            //valVal is 'SFields:'            //val = NULL;        }    }  

Using these types will make your life considerably easier and if you make the change it may just fix your problem too.

PREVIOUS: So you can be CERTAIN that the string is not being passed in correctly add a printline just before the strlen call. Once you do this work backward with printlines until you find where the string is not being set. This is a basic debugging technique.

Label(int row,               int column,               const char *s,               int length = 0) :                   LField(row, column, length, s, false) {    }        LField(int rowNumVal,                        int colNumVal,                        int widthVal,                        const char *valVal = "",                        bool canEditVal = true)           {               std::cout << valVal << std::endl;              if(strlen(valVal) > 0)               {                }              else {                              //This is where it jumps to, even though the value in                                                                      //valVal is 'SFields:'                  val = NULL;              }          }  


Solution:2

<LANGUAGE FEATURE XXXX IS BROKEN>! ... No, it isn't.

Just before measuring the string, write in a puts(valVal), to ensure you are not mistaken about the contents of that variable.


Solution:3

Whenever there is strange behavior like this, memory getting screwed up is almost always the culprit. Never mix new with delete[] OR new[] with delete. The latter is slightly worse than the former but they are both bad news. delete[] should only be used in conjunction with new[]. Mixing these allocation/deallocation notations will result in undefined behavior. Since you are never using new[], replace all of your delete[] calls with delete. It is also good practice and good manners to set your pointers to NULL after you delete them. It is highly unlikely that you will be the only one debugging this code and it would be extremely annoying to debug your pointers thinking that there is valid memory there, when in fact there isn't.

Mixing these notations inevitably lead to exploits and memory leaks.


Solution:4

There is a problem here:

LField(const LField &clone) {       delete[] val;      val = new char[strlen(clone.val) + 1];   

val is uninitialized when the constructor is called, and you are deleting it.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »