传递到构造函数的值超出范围后会发生什么情况?
我一直在寻找这个问题的答案,但没有发现任何与我的问题类似的东西。
我有一个类,我们称之为 Foo
,它的构造函数中带有一个 const char*
指针。在我的代码中,我需要创建一个新的 Foo
,并将 std::string
的 .data()
作为参数。问题是,一旦字符串超出范围,传递给 Foo 的值(或指针,这是我感到困惑的地方..)就会变得无效。
所以现在字符串无效,Foo 的 const char*
也无效。
如何将字符串数据的值传递到 Foo
中,以便在字符串超出范围时它不会变得无效?
I've been searching around for the answer to this and haven't found anything that was similar to my problem.
I have a class, let's call it Foo
, that takes a const char*
pointer in it's constructor. In my code, I need to create a new Foo
with a std::string
's .data()
as the parameter. The problem is, once the string falls out of scope, the value (or pointer, this is where I'm getting confused..) passed to Foo becomes invalid.
So now that the string is invalid, the Foo's const char*
is invalid.
How can I pass the value of the string's data into Foo
so that it won't become invalid once the string falls out of scope?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为什么不直接复制该字符串呢?这样你就知道它不会消失。如果您不知道 const char * 将在类的生命周期中存在,您需要复制它(或者做一些不同的事情,例如将字符串包装在引用计数器中)
Why don't you just make a copy of the string? That way you know it will not disappear. If you don't know the const char * is going to be around for the duration of your class's life you need to copy it (or do something different like have the string wrapped in a reference counter)
如果您需要将字符串保存到构造函数的调用范围之外,您可能应该将其复制到
Foo
中进行存储。You should probably be copying the string inside
Foo
to store it if you need it to last past the constructor's calling scope.您有两个选择:(
std::string
中即可。new[]
分配您自己的char*
,并将数据strcpy
放入构造函数中的新char*
中。然后,您还需要定义一个析构函数来删除delete[]
Foo
的char*
。然后,就像通常的情况一样,三法则,您还需要定义复制构造函数和复制赋值运算符来分配它们自己的新char*
(在复制赋值运算符delete[]
的情况下,旧的char*
)并从原始Foo
复制char*
。很容易犯错误并造成内存泄漏,或因尝试访问已释放的内存而随机崩溃。x
我很有可能遗漏了一些东西,因为这超出了我的想象,但我相信有人会好心地在评论中指出这一点。
另外,使用 Boost 中的
shared_ptr
可能会让您的选项 #2 的生活更轻松,但我对此没有太多经验,而且对于一个小项目来说它可能有点繁重。还有一条评论。您确实应该使用
string.c_str
(与string.data
相反,因为它添加了您需要的 NULL 字符。You have two options:
std::string
in your class.char*
withnew[]
, andstrcpy
the data into your newchar*
in your constructor. Then you'll also need to define a destructor todelete[]
Foo
'schar*
. Then, as is usually the case with the Rule of Three, you'll need to define copy constructor and copy assignment operators as well to allocate their own newchar*
(and in the case of the copy assignment operatordelete[]
the oldchar*
) and copy the thechar*
from the originalFoo
. Very easy to make a mistake and create a memory leak, or random crashing from trying to access freed memory.x
There's a good chance I left out something as this is off the top of my head, but I'm sure someone will be kind enough to point it out in the comments.
Also, using the
shared_ptr
from Boost may make your life easier for option #2, but I don't have much experience with it, and it might be a little heavy to use for just a small project.And one more comment. You should really be using
string.c_str
as well (as opposed tostring.data
) as it adds the NULL character you'll need.仅提供描述无助于破译代码中发生的错误。
std::string::data()
返回指向字符数组的起始字符的指针。只要传递的内存位置不失效,类成员和传递的参数都指向同一位置。如果您看到,传递的参数超出了范围(即,它不再有效),那么您的类成员就变成了悬空指针。在这种情况下,最好复制传递的字符串。这应该会给你一个想法 -输出:我是一个字符串
IdeOne。希望这有帮助!
Just giving the description won't help to decipher what wrong is going on in your code.
std::string::data()
returns the pointer to the beginning character of the array of characters. As long as the memory location passed doesn't go invalid, both the class member and the passed parameter point to the same location. If you see that, the passed parameter goes out of scope( i.e., it is no more valid ) then your class member becomes a dangling pointer. In that case, better to do a copy of the passed string. This should give you an idea -Output: I am a string
IdeOne. Hope this helps !
复制它。在引用计数友好的语言中,您将“保留”字符串。但这是C++。如果您不复制它,则出现悬空指针的风险很高。
或
或
如您所见,
std::string
选项更容易。Copy it. In a refcount friendly language you would "retain" the string. But this is C++. You have a high risk of dangling pointers if you do not copy it.
or
or
As you can see, the
std::string
option is easier.