当用作参数时,字符串是否更改const char *

时间:2014-07-18 16:40:47

标签: c++ string

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

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

enter image description here

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

我想在最初提出问题,但在添加代码之前发布。附件是它的使用片段和我之前找不到的缺失字符符号的正确图片。

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 Class)

...
//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 ++ Class)

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

1 个答案:

答案 0 :(得分:4)

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

当一个函数返回一个类类型(直接,而不是对类型的引用)时,调用该函数会创建一个临时的类对象,该对象一直存在,直到调用它的全表达式结束。 (最常见的&#34;完整表达式&#34;就像在这种情况下的声明一样。)

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

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

在你的测试运行中,无效指针所指向的内存恰好仍然包含一些&#34;期望&#34;第一次打印时的数据。但是第二次,其他一些代码显然已经将这个内存区域重用于其他东西。