【问题标题】:Segmentation fault in constructor when using strcpy使用 strcpy 时构造函数中的分段错误
【发布时间】:2014-04-06 05:43:38
【问题描述】:

大家好,我正在编写一个程序来读取大学作业的 NMEA 句子,但我遇到了分段错误的问题。谁能帮我解决一下,好吗?

NmeaSentence::NmeaSentence(std::string sentence) {
    const char *temp = sentence.c_str();
    char *c_sent;
    strcpy(c_sent, temp);
    char *pch;
    for(int i = 0; i < MAX_SENTENCE_PARTS; i++){
        pch = strtok(c_sent, ",");
        this->sentenceParts[i] = pch;
    }
    this->sentence = sentence;
    this->sentenceType = sentenceParts[0];
}

错误似乎发生在 strcpy。我做错了什么?

【问题讨论】:

  • strcpy with malloc? 的可能重复项
  • 附带说明,为什么不在任何地方使用std::string?是否有特定需求迫使您通过(const) char * 操作字符串?
  • 您使用的是strtok。那是大错特错了。考虑使用 Boost.Tokenizer,或来自 Boost.StringAlgo 的split
  • @Will 看来您没有阅读所有答案。

标签: c++


【解决方案1】:

您没有为c_sent 分配内存。这是未定义的行为。

使用char *c_sent = new char[sentence.size() + 1];。我为空终止符添加了空间。不要忘记在函数退出前调用delete[] c_sent;

(顺便说一句,tempsentence 的生命周期内有效,除非以任何方式对其进行修改。)。

【讨论】:

  • 其实在句子被修改之前都是有效的,所以谨慎的做法是让句子为const。
  • 我不完全确定,我是 C++ 新手
  • @heinrichj:这是一个很好的观点。更好的是,将const std::string&amp; sentence 作为函数参数传递。
  • @Will 如果您是 C++ 新手,我能给您的最佳建议是尽可能使用std::string。删除所有旧的 char* 东西。
【解决方案2】:

临时字符串 c_sent 未初始化。

char * c_sent

char * c_sent = strdup(sentence.c_str());

在退出之前不要忘记释放。

free(c_sent);

这样你就不需要温度了。

【讨论】:

  • 我们在这里使用 C++,我建议不要使用 free 等。
  • 好吧,如果你用的是strtok,那还不如用strdup和free。
  • @Bathsheba 你必须使用freestrdup,尽管使用strdupmay not be 一个好主意。
【解决方案3】:

成员函数有几个缺陷。

如果函数的参数没有改变,那么最好将函数声明为

NmeaSentence::NmeaSentence( const std::string & sentence);

正如已经说过的那样,您没有在要复制句子的地方分配内存。指针 c_sent 没有被分配的内存地址初始化。

第二个缺陷是 pch 总是指向 c_sent 中的同一个地址,因为你错误地使用了函数 strtok。您应该按照以下方式使用它

char *pch = strtok(c_sent, ",");
for(int i = 0; i < MAX_SENTENCE_PARTS && pch; i++){
    this->sentenceParts[i] = pch;
    pch = strtok( NULL, ",");
}

还不清楚如何确定字符串包含多少部分。

【讨论】:

    猜你喜欢
    • 2020-04-20
    • 2013-03-13
    • 2018-12-15
    • 2015-02-28
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多