strlen()不工作

时间:2010-06-29 23:04:05

标签: c++

基本上,我将一个指向字符串的指针传递给我的构造函数,然后在传递字符串值时初始化它的基本构造函数。由于某种原因,strlen()不起作用,所以它不会进入如果声明权利。我检查过以确保变量中有值,并且存在。

这是我的代码,我已经删除了所有不相关的部分:

标签类内容:

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类内容:

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;
}

屏幕类内容:

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;
    }
};

主:

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

希望有人能够看到我做错了什么。

4 个答案:

答案 0 :(得分:3)

&lt;语言功能XXXX已被破坏&gt;! ......不,不是。

在测量字符串之前,写入puts(valVal),以确保您没有误解该变量的内容。

答案 1 :(得分:2)

Marcin在这一点上问题将归结为调试问题,我复制了你的代码并略微遗漏并得到了正确的结果。

现在需要说明的是,你应该使用更多的C ++惯用代码。例如,您应该使用std::string而不是const char *和std::vector而不是原始数组。

以下是使用std::string

的LField构造函数的示例
#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;
      }
  }

使用这些类型会让您的生活变得更加轻松,如果您进行更改,它也可以解决您的问题。

PREVIOUS: 因此,您可以确保在strlen调用之前未正确传递字符串添加打印行。一旦您使用printlines向后工作,直到找到未设置字符串的位置。这是一种基本的调试技术。

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;
            }
        }

答案 2 :(得分:0)

每当出现这种奇怪的行为时,内存被搞砸几乎总是罪魁祸首。切勿将删除[] 新[] 删除混合使用。后者比前者略差,但它们都是坏消息。 删除[] 只应与 new [] 一起使用。混合这些分配/释放符号将导致未定义的行为。由于您从未使用 new [] ,请使用删除替换所有删除[] 来电。删除它们后,将指针设置为 NULL 也是一种很好的做法和良好的举止。你不可能是唯一一个调试这个代码的人,调试你的指针认为那里有有效的内存是非常烦人的,而实际上却没有。

混合这些notations不可避免地会导致exploitsmemory leaks

答案 3 :(得分:0)

这里有一个问题:

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

值在调用构造函数时未初始化,并且您要删除它。