基于strlen的意外成功复制 我用C++中的指针和缓冲区来复习我的技能。我尝试了下面的代码,一切正常。没有泄漏,没有碰撞,什么都没有
说实话,我没想到会这样 当我调用基于strlen的意外成功复制 我用C++中的指针和缓冲区来复习我的技能。我尝试了下面的代码,一切正常。没有泄漏,没有碰撞,什么都没有,c++,string,buffer,memcpy,C++,String,Buffer,Memcpy,说实话,我没想到会这样 当我调用char*buf2=new char[strlen(buf)]时,我没想到srlen(buf)会返回正确的大小。我一直认为斯特伦 需要以NULL结尾的字符串才能工作。这里的情况并非如此,那么为什么它会运行此代码呢 int main(){ const char* mystr = "mineminemine"; char* buf = new char[strlen(mystr)];
char*buf2=new char[strlen(buf)]
时,我没想到srlen(buf)
会返回正确的大小。我一直认为斯特伦
需要以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;
}
这就是所谓的未定义行为——程序似乎在工作,但你不能依赖它 当分配内存时,在某个地方会出现一个空字符,它足够接近缓冲区的开始,程序可以从技术上访问该空字符和缓冲区开始之间的所有内存,因此您不会观察到崩溃
你不能相信那种行为。不要这样编写代码,始终分配足够的空间来存储终止的空字符。这称为未定义行为-程序似乎正在运行,但您不能依赖于此 当分配内存时,在某个地方会出现一个空字符,它足够接近缓冲区的开始,程序可以从技术上访问该空字符和缓冲区开始之间的所有内存,因此您不会观察到崩溃
你不能相信那种行为。不要这样编写代码,请始终分配足够的空间来存储终止的空字符。请考虑另一种方法来执行相同的操作:
int main(){
std::string mystr = "mineminemine";
std::string mystr2 = mystr;
}
在内部,您有一个添加了空终止字符的缓冲区。复制标准字符串时,不必担心跟踪缓冲区的开始和结束
现在考虑到字符串的生存期,这两个变量在堆栈上声明,并在main超出范围时销毁(例如terminationa)。如果您需要在对象之间共享字符串,并且您不一定知道它们将在何时销毁,我建议您考虑使用boost共享指针。考虑另一种方法来完成同样的事情:
int main(){
std::string mystr = "mineminemine";
std::string mystr2 = mystr;
}
在内部,您有一个添加了空终止字符的缓冲区。复制标准字符串时,不必担心跟踪缓冲区的开始和结束
现在考虑到字符串的生存期,这两个变量在堆栈上声明,并在main超出范围时销毁(例如terminationa)。如果您需要在对象之间共享字符串,并且您不一定知道它们何时会被销毁,我建议您考虑使用boost共享指针。只需添加一个观察值-您必须分配新字符[strlen(buf)+1];对于一个空的终止字符,请参阅。我问题的要点是,没有“strlen(buf)+1”,一切都可以正常工作。真的“未定义”吗?这取决于记忆的内容,但我认为斯特伦没有发生任何不确定的行为。编辑:当然,我错了。越界数组访问是未定义行为的典型示例。只需再添加一个观察值-您必须分配新字符[strlen(buf)+1];对于一个空的终止字符,请参阅。我问题的要点是,没有“strlen(buf)+1”,一切都可以正常工作。真的“未定义”吗?这取决于记忆的内容,但我认为斯特伦没有发生任何不确定的行为。编辑:当然,我错了。越界数组访问是未定义行为的典型示例。Doh。