c++ - PPP Stroustrup 练习 - 将 C 风格的字符串复制到它在自由存储上分配的内存中
问题描述
我正在解决 Stroustrup 的 PPP 书中的以下练习(17.4):
编写一个函数
char* strdup(const char* )
,将 C 风格的字符串复制到它在空闲存储上分配的内存中。不要使用任何标准库函数。
这是我的实现,编译得很好。我对运行该函数时发现的错误消息有疑问。
#include <iostream>
#include <string>
char* strdup(const char* s) {
if (s==0) return 0;
// get number of char in s
int n = 0;
while (s[n] != 0)
++n;
// allocate memory with room for terminating 0
char* pc = new char[n+1];
// copy string
for (int i = 0; s[i]; ++i)
pc[i] = s[i];
pc[n] = 0; // zero at the end: it's a C-style string
delete[] s;
return pc;
}
int main()
try {
std::string str;
char* cstr;
while (std::cin>>str && str!="quit") {
cstr = strdup(&str[0]);
std::cout << cstr << "\n";
delete[] cstr;
}
}
catch (std::exception& e) {
std::cerr << "exception: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "exception\n";
}
它可以编译,但是当我运行它并写入第一个字符时,出现pointer being freed was not allocated
错误。如果我删除delete[] s
,那么我没有内存泄漏,它运行得很好。但是为什么(显然)不这样做是正确delete[]
的s
?是不是因为没有被分配new
?
解决方案
Astd::string
确实管理它用于存储字符串的内存。在main
你做
std::string str;
和
cstr = strdup(&str[0]);
但是您对参数的strdup
调用。delete[] s;
这是你已经知道的。现在考虑析构函数std::string
在超出范围时确实已经清理了内存。使用的缓冲区std::string
不能被删除两次。你不许叫delete
。&str[0]
您只需要delete
通过创建的对象new
。
还有小字符串优化。在这种情况下&str[0]
,不指向您可以删除的堆分配缓冲区。
PS:0
当您应该使用nullptr
指针和'\0'
空终止符时,您正在使用。
推荐阅读
- java - Java方法中的双重初始化是什么意思
- visual-studio-2019 - 如何在 VS 2019 的启动状态下启用新闻窗格?
- typescript - TSLint 对未按字母顺序排列的导入源不满意
- django - Django docker - 无法将主机名“db”转换为地址:提供节点名或服务名,或未知
- javascript - JS Regex: (a|b) 匹配子表达式的 a 或 b 部分。a 和 b 切换时的不同行为
- systemd - 为什么 udev 不会触发已挂载的 sdcard 分区的删除事件?
- reactjs - 带有嵌套 CheckBoxGroupInput 的 ReferenceInput 行为异常
- java - 为什么 Java 不使用 ArrayList
对象作为集合 目的? - c - 将文本文件中的一行拆分为C中的单独变量
- javascript - Testcafe LocalStorage 的问题