普通char指针与make_unique处理iostream输入差异及字符数组存储方法
问题解析与解决方案
先拆解你遇到的几个核心问题,一步步帮你理清逻辑:
一、普通char*的“诡异表现”:本质是危险的野指针!
你看到char* str2;用cin>>str2后能输出字符串,其实是未定义行为——因为str2是个未初始化的野指针,它指向的是内存里的随机地址。cin>>str2会把输入的字符串往这个随机地址写,运气好没触发崩溃,再加上cout对char*有特殊重载:它会把char*当成C风格字符串,从指针指向的位置开始输出,直到遇到'\0'终止符。而cout<<&str2输出的是指针变量str2本身在栈上的地址,不是它指向的内容,这就是两者的区别。
⚠️ 注意:这种写法绝对不能用,野指针写入会导致内存破坏、程序崩溃甚至安全问题!
二、为什么make_unique<char>()会出错?
make_unique<char>()只分配了单个char的内存空间,而cin>>str3Ptr试图往里面写入一整个字符串(长度远大于1),这直接导致内存越界。另外,unique_ptr<char>本身并没有重载operator>>,你需要用.get()获取它管理的原始指针,但即使这么做,单个char的空间也装不下字符串,必然触发错误或崩溃。
三、用make_unique正确存储输入字符串的方法
要存储C风格字符串,你需要分配足够长度的char数组(包括末尾的'\0')。推荐的做法是先读取std::string(它会自动管理内存),再根据字符串长度分配动态char数组,最后拷贝内容:
修正后的代码:
#include<iostream> #include<string> #include<memory> #include<algorithm> // 用于std::copy using namespace std; int main(){ // using of std::string (最安全的方式) string str; cout<<"Enter a str: "; cin>>str; cout<<"\n"<<str<<"\n"; // 用make_unique<char[]>存储C风格字符串的正确方式 cout<<"Enter a str for unique_ptr: "; string tempStr; cin>>tempStr; // 分配长度为tempStr.size()+1的数组,+1是为了存储'\0' auto str3Ptr = make_unique<char[]>(tempStr.size() + 1); // 把string的内容拷贝到char数组里 copy(tempStr.begin(), tempStr.end(), str3Ptr.get()); // 手动添加终止符,确保cout能正确识别为C风格字符串 str3Ptr[tempStr.size()] = '\0'; // 输出C风格字符串,需要用.get()获取原始指针 cout<<"\n"<<str3Ptr.get()<<endl; return 0; }
关键要点:
- 用
make_unique<char[]>(n)来分配动态char数组,n是数组的长度(必须包含'\0'的位置) - 先通过
std::string读取输入,避免手动处理输入长度的麻烦 - 用
std::copy或strcpy(需要引入<cstring>)把字符串内容拷贝到动态数组,最后手动添加'\0'终止符 - 输出时要用
.get()获取unique_ptr<char[]>管理的原始指针,cout才能识别为C风格字符串
内容的提问来源于stack exchange,提问作者asmmo
相关产品推荐
相关产品推荐

