【问题标题】:Having issues with initializing character array初始化字符数组时遇到问题
【发布时间】:2011-02-17 18:27:00
【问题描述】:

好的,这是关于哈希表的家庭作业,但这是我认为我在之前的课程中能够做到的简单事情,但我正在撕毁我的头发。教授反应不够快,所以我想我会在这里尝试。

我们有一个股票对象的哈希表。股票对象是这样创建的:

stock("IBM", "International Business Machines", 2573, date(date::MAY, 23, 1967))

我的构造函数看起来像:

stock::stock(char const * const symbol, char const * const name, int sharePrice, date priceDate): m_symbol(NULL), m_name(NULL), sharePrice(sharePrice), dateOfPrice(priceDate)
{    
setSymbol(symbol);
setName(name);
}

setSymbol 看起来像这样:(setName 是相同的):

void stock::setSymbol(const char* symbol)  
{  
if (m_symbol)  
    delete [] m_symbol;  
m_symbol = new char[strlen(symbol)+1];  
strcpy(m_symbol,symbol);  
}  

它拒绝分配就行了

m_symbol = new char[strlen(symbol)+1];

使用 std::bad_alloc。名称和符号已声明

char * m_name;  
char * m_symbol;

肯定是 strlen() 误入歧途。而且似乎并非每次都发生。

cout << symbol << strlen(symbol); 

正确返回 IBM,然后崩溃

【问题讨论】:

  • name和symbol是类变量,以及构造函数和setSymbol方法中的函数参数。可能有点混乱。
  • 在失败的行之前执行std::cout &lt;&lt; strlen(symbol)。检查字符串长度值是否有意义。
  • 您应该为您的成员变量采用命名约定。两个流行的是memberVariable_m_memberVariable。这样的约定将更容易区分参数名称和成员变量名称。
  • 某些指针操作错误可能会导致“IBM”之后的终止 '\0\' 被覆盖,从而导致虚假的 strlen 值。
  • 您是否在定义自己的复制构造函数和赋值运算符?如果你不这样做,编译器生成的默认值将对你的成员变量执行浅拷贝(这不是你想要的)。见en.wikipedia.org/wiki/Object_copystackoverflow.com/questions/184710/…

标签: c++ arrays pointers cstring


【解决方案1】:

由于这是标记为 C++,您可以使用 std::string 而不是自己在 char* 上进行所有指针维护吗?

std::string name;
std::string symbol

那么setSymbol就变得简单了:

void stock::setSymbol(const char* symbol)  
{
    this->symbol = symbol;
}

【讨论】:

  • 我非常讨厌 C++ 老师要求学生使用 C 做事的方式,除了老师是一名 C 程序员,戴着写着++ 的帽子。知道字符串是如何工作的当然很有价值,但是当它妨碍对其他概念的理解时,要求它是没有理智的。
  • @Quandrum:进行转换可能会更容易,只是看看它是否修复了当前的错误,然后再切换回来。
【解决方案2】:

你调用的时候symbol参数肯定有问题

新字符[strlen(symbol)+1];

strlen 返回 C++ 运行时无法分配的巨大长度。如果symbol 在开头未初始化char* 指针,这是很有可能的。它不会一直失败,不是吗?

【讨论】:

  • 我猜变量同名会让人困惑。 strlen(symbol)中的符号为函数参数,此时指向字符串“IBM”。 this->symbol 是一个类变量,此时为空指针。但是,它不会一直失败。你是对的。
  • 一个愚蠢的问题(我会测试如果我手头有一个编译器,但现在我没有):'symbol' 参数和'symbol' 实例变量是否可能会以某种方式混合向上 ?所以在运行时 strlen 会在一个未初始化的字符串上运行并给出一个虚假的长度......直觉上,你会认为编译器不会被愚弄,但对于 C++,你永远不知道 ;)
  • @phtrivier:这不是一个愚蠢的问题。这个问题被称为变量阴影:en.wikipedia.org/wiki/Variable_shadowing
  • @emile :感谢您的链接...正如您在其他地方指出的那样,通过对成员/静态/局部变量使用不同的命名约定,您可以透明地摆脱这种错误...但是随后选择约定为无尽的巨魔打开了大门;)
【解决方案3】:

我能够在 Cygwin 上毫无问题地运行代码,所以我猜想在区分参数 symbol 和成员 symbol 时依赖于实现。

你自己说这很令人困惑——那就做点什么吧!!!我可以建议,永远不要再将参数命名为与局部/成员变量相同的名称。 (它不仅消除了混淆,您无需使用this-&gt; 消除成员变量的歧义。)

【讨论】:

  • 有时我的运行没有问题......即使我更改了变量名称以使其不会混淆。
【解决方案4】:

感谢所有提供帮助的人。我和我的教授一起检查了它,不幸的是我之前溢出了一个数组并破坏了堆,这在此处表现出来。

不过,这对我来说是一次很好的谈话。它帮助我思考我刚刚做的一些事情。所以再次感谢SO'ers

【讨论】:

    猜你喜欢
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多