基本上,我将一个指向字符串的指针传递给我的构造函数,然后在传递字符串值时初始化它的基本构造函数。由于某种原因,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:");
}
希望有人能够看到我做错了什么。
答案 0 :(得分:3)
&lt;语言功能XXXX已被破坏&gt;! ......不,不是。
在测量字符串之前,写入puts(valVal)
,以确保您没有误解该变量的内容。
答案 1 :(得分:2)
Marcin在这一点上问题将归结为调试问题,我复制了你的代码并略微遗漏并得到了正确的结果。
现在需要说明的是,你应该使用更多的C ++惯用代码。例如,您应该使用std::string
而不是const char *和std::vector
而不是原始数组。
以下是使用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;
}
}
使用这些类型会让您的生活变得更加轻松,如果您进行更改,它也可以解决您的问题。
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不可避免地会导致exploits和memory leaks。
答案 3 :(得分:0)
这里有一个问题:
LField(const LField &clone) {
delete[] val;
val = new char[strlen(clone.val) + 1];
值在调用构造函数时未初始化,并且您要删除它。