【问题标题】:Does string change const char * when used as parameter字符串用作参数时是否更改 const char *
【发布时间】:2014-07-18 16:40:46
【问题描述】:

很好奇构造函数字符串 (const char* s) 有时会更改 const char * 中的字符的原因。我有一个简单的方法来检查是否设置了标志以某种方式更改字符串搜索树并返回一个值。如果我只使用字符串,它似乎工作正常;但是由于某些奇怪的原因,当我使用从另一个函数接收的 const char * 作为函数的参数时,我收到的 const char * 有时返回不完整。这是导致我直到最近才发现的细微错误的原因。如果在方法内部创建另一个字符串并将字符串参数附加到新字符串,它似乎可以工作,但这似乎是解决此问题的错误方法。我相信这可能是对正确使用构造函数的误解,有没有人对这个微妙的问题有任何见解?

作为一个简单的例子,终端返回以下结果,注意不完整字符的符号没有正确复制,而是空白。

编辑:
@T.C.
我绝不会责怪字符串类 T.C.,我很清楚这是我的错误,我正试图理解这个问题。这很可能是对 std::string 类中构造函数的使用的误解。一些背景故事我正在使用 C/C++ 和 java 一起练习。我创建了一个似乎在 C++ 中通过了最少测试的类,并创建了一个包装器,以便我可以在 C 中使用它。当我将字符串作为参数而不是 const char * 传递时,它可以正常工作;但是据我所知,std::string 应该复制字符,尽管我不确定。我知道当个人将两者混合时,人们会告诉我只使用 C++ 而不是在其他问题的答案中混合两者,但任何方向都会受到赞赏。

我原本想让问题简短,但在添加代码之前发布。附件是它的使用的 sn-p 和我之前找不到的丢失字符符号的正确图片。

LZW.c(C类)

...
const char * tex = Trie_Int_longestPrefix(trie,input); //Find max prefix match tex
printf("%25s\t",tex);
//FOR SOME REASON TEX CHANGES AFTER THIS CALL
arr[size++] = Trie_Int_get(trie,tex);   //Add encoding 
printf("%25s\n",tex);
int t = strlen(tex);
...

ctrie.cpp(C-Wrapper 类)

...
//Return Value
int Trie_Int_get(Trie_Int * t,const char * key){return ((Trie<int> *)t)->get(key); }
...
//Find and return longest prefix of s in TST
const char * Trie_Int_longestPrefix(Trie_Int * t,const char * s){return  ((Trie<int> *)t)->longestPrefix(s).c_str();}
...

Trie.ii(C++ 类)

...
template<typename value>
value Trie<value>::get(std::string key,const bool & ignoreCase) const {
    if(key.empty()){throw std::invalid_argument("key must have length >= 1");}
    if(ignoreCase)__toLowerCase(key);
    TrieNode* x = get(root,key,0,ignoreCase);
    return x!=nullptr? x->val : defVal;
}
template<typename value>
std::string Trie<value>::longestPrefix(std::string key,const bool & ignoreCase) const{
...Kind of Long
}
...

【问题讨论】:

  • 可能与string 无关,而与您代码的其他部分有关。
  • 请发布出现问题的代码。
  • 您的代码中有错误。如果您需要帮助识别错误,您必须发布一个小的、独立的示例来重现问题。
  • 关于代码的一件事是......你知道,它是代码,你不必描述它,你可以展示实际的代码。发布一个能够重现问题的小型、独立的示例。
  • @T.C.我从来没有说过这是字符串类的问题,假设问题是我自己的问题是其他任何人的问题会有点令人讨厌

标签: c++ string


【解决方案1】:
template<typename value>
std::string Trie<value>::longestPrefix(
    std::string key,const bool & ignoreCase) const;

//Find and return longest prefix of s in TST
const char * Trie_Int_longestPrefix(Trie_Int * t,const char * s)
{return  ((Trie<int> *)t)->longestPrefix(s).c_str();}

当一个函数返回一个类类型(直接,而不是对类型的引用)时,调用该函数会创建一个临时类对象,该对象将一直存在到调用它的完整表达式的末尾。 (在这种情况下,最常见的“完整表达式”是一个语句。)

std::string::c_str() 返回一个 C 字符串指针,该指针保证在调用 string 的任何非常量成员(包括析构函数)之前一直有效。

所以Trie_Int_longestPrefix 函数返回一个已经无效的指针,任何对它的使用都算作未定义的行为。

在您的测试运行中,无效指针指向的内存恰好在您第一次打印时仍包含一些“预期”数据。但到第二次时,其他一些代码显然已经将该内存区域重用于其他用途。

【讨论】:

  • 啊,我明白了,谢谢。在我离开该方法后,我最初对为什么 c_str() 完全起作用感到困惑;所以最初尝试使用结构,但恢复为简单地为它分配空间,在我修复了另一个问题后,决定这两种方法看起来有点混乱,因为当我检查值时我从来没有看到差异,所以我认为它没问题。我想我必须简单地分配内存并记住在函数之外删除它。
猜你喜欢
  • 1970-01-01
  • 2013-10-22
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
  • 2011-08-16
  • 2011-10-19
  • 2018-09-25
相关资源
最近更新 更多