基于 strlen 的意外成功复制
我正在复习我在 C++ 中使用指针和缓冲区的技能。我尝试了下面的代码,一切正常。没有泄漏,没有崩溃,什么都没有。
说实话我没想到会这样。
当我调用 char* buf2 = new char[strlen(buf)] 时,我没想到 srlen(buf) 返回正确的大小。我一直认为 strlen
需要一个以 NULL 结尾的字符串才能工作。这里的情况并非如此,那么为什么这段代码会起作用呢?
int main(){
const char* mystr = "mineminemine";
char* buf = new char[strlen(mystr)];
memcpy(buf, mystr, strlen(mystr));
char* buf2 = new char[strlen(buf)];
memcpy(buf2, buf, strlen(buf));
delete[] buf2;
delete[] buf;
}
I was reviewing my skills with pointers and buffer in C++. I tried the code below and everything works fine. No leaks, no crash, nothing.
To be honest I didn't expect this.
When I call char* buf2 = new char[strlen(buf)]
I didn't expect srlen(buf)
returning the right size. I always thought that strlen
needs a NULL terminated string to work. Here it is not the case so why it is working this code?
int main(){
const char* mystr = "mineminemine";
char* buf = new char[strlen(mystr)];
memcpy(buf, mystr, strlen(mystr));
char* buf2 = new char[strlen(buf)];
memcpy(buf2, buf, strlen(buf));
delete[] buf2;
delete[] buf;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这就是所谓的未定义行为——程序看起来可以工作,但你不能依赖它。
分配内存时,在距离缓冲区开头足够近的地方会出现一个空字符,并且从技术上讲,程序可以访问该空字符和缓冲区开头之间的所有内存,因此您不会观察到崩溃。
你不能依赖这种行为。不要编写这样的代码,始终分配足够的空间来存储终止空字符。
That's called undefined behavior - the program appears working but you can't rely on that.
When memory is allocated there happens a null character somewhere that is close enough to the start of the buffer and the program can technically access all memory between that null character and the start of the buffer so you don't observe a crash.
You can't rely on that behavior. Don't write code like that, always allocate enough space to store the terminating null character.
考虑另一种方法来完成同样的事情:
在内部,您有一个添加了空终止字符的缓冲区。当您复制标准字符串时,您不必担心跟踪缓冲区的开头和结尾。
现在考虑字符串的生命周期,这两个变量在堆栈上声明,并在 main 超出范围(例如终止a)时销毁。如果您需要在对象之间共享字符串并且您不一定知道它们何时会被销毁,我建议考虑使用 boost 共享指针。
Consider another way to do the same thing:
Internally you have a buffer with a null terminating character added. When you copy a standard string you don't have to worry about keeping track of the start and end of the buffer.
Now considering the lifetime of the strings these two variables are declared on the stack and destroyed when main goes out of scope (e.g. terminationa). If you need strings to be shared amongst objects and you do not necessarily know when they will be destroyed I recommend considering using boost shared pointers.