正确填充字符指针
Posted
技术标签:
【中文标题】正确填充字符指针【英文标题】:Filling char pointer correctly 【发布时间】:2019-05-08 13:45:37 【问题描述】:我有一个字符指针:
char* s = new char[150];
现在我该如何填写?这个:
s="abcdef";
给出关于字符串文字和char*
之间转换的弃用警告,但通常有效。
这个:
char* s = new[150]("abcdef");
不工作,报错。
如何正确执行此操作?请注意,我希望内存分配具有 150*sizeof(char) 字节并包含“abcdef”。我知道 malloc,但是可以用 new 做吗?
它用于我无法使用标准库的作业。
【问题讨论】:
转到你书中关于 C 字符串和strcpy
的那一页,然后放弃这种方法并使用std::string
。
为什么不能用?
@user74200 问题中应提及库限制。如果您不允许使用标准库,您将不得不编写自己的字符串复制函数(这是一个非常常见的家庭作业......)。
@user74200 我知道 std::string,但不能使用它 -- std::string
成为标准 C++ 的一部分已有 21 年了。那是整整一代人。如果不使用它,你学到的只是如何编写不安全的 C++ 代码。
s="abcdef";
只是通过重新分配指针来泄漏您在另一行分配的内存。 (由于 const 差异,它不应该从 C++11 开始编译。)
【参考方案1】:
这一系列语句
char* s = new char[150];
s="abcdef";
导致内存泄漏,因为首先分配了内存并将其地址分配给指针s
,然后用字符串文字"abcdef"
的地址重新分配指针。此外,C++ 中的字符串文字(与 C 相对)具有常量字符数组的类型。
如果您为字符串分配了内存,那么您应该使用 C 标准函数 strcpy
或 C 标准函数 strncpy
将字符串复制到内存中。
例如
char* s = new char[150];
std::strcpy( s, "abcdef" );
或者
const size_t N = 150;
char* s = new char[N];
std::strncpy( s, "abcdef", N );
s[N-1] = '\0';
甚至是以下方式
#include <iostream>
#include <cstring>
int main()
const size_t N = 150;
char *s = new char[N] '\0' ;
std::strncpy( s, "abcdef", N - 1 );
std::cout << s << '\n';
delete []s;
无论如何,最好只使用标准类std::string
。
std::string s( "abcdef" );
例如
std::string s;
s.assign( "abcdef" );
【讨论】:
【参考方案2】:在不使用C++标准库的情况下,为字符串创建内存区域然后填充它的基本过程如下:
用new
创建合适大小的内存区域
使用循环将字符串中的字符复制到新区域中
所以源代码看起来像:
// function to copy a zero terminated char string to a new char string.
// loop requires a zero terminated char string as the source.
char *strcpyX (char *dest, const char *source)
char *destSave = dest; // save copy of the destination address to return
while (*dest++ = *source++); // copy characters up to and including zero terminator.
return destSave; // return destination pointer per standard library strcpy()
// somewhere in your code
char *s1 = new char [150];
strcpyX (s1, "abcdef");
【讨论】:
你的strcpyX
和库函数std::strcpy
有什么区别?为什么要重新发明***?
库版本strcpy()
可以针对目标平台进行优化;你的不是。
@ThomasMatthews 如果您阅读了 cmets,这就是帖子所要求的,替代标准 strcpy()
。我知道标准库已经过优化,等等。那不是这篇文章的内容。这似乎是一项课堂作业。【参考方案3】:
给定一个字符数组:
char * s = new char [256];
指针的填充方法如下:
std::fill(&s, &s + sizeof(s), 0);
以下是填充 数组的方法:
std::fill(s, s+256, '\0');
以下是分配或复制文本到数组的方法:
std::strcpy(s, "Hello");
你也可以使用std::copy
:
static const char text[] = "World";
std::copy(text, text + sizeof(text), s);
请记住,指针、数组和 C-Style 字符串是不同的概念和对象。
编辑 1:首选std::string
在 C++ 中,更喜欢将 std::string
用于文本而不是字符数组。
std::string s;
s = "abcdef";
std::cout << s << "\n";
【讨论】:
另见:strcat
、strchr
、strncpy
和 strncat
。【参考方案4】:
为该字符串分配内存后,您可以使用strcpy
来填充它:
strcpy(s, "abcdef");
【讨论】:
strncpy
通常被宣传为更安全的strcpy
,但复制 c 字符串也很糟糕。如果您的数组太小,它不保证空终止。它还用额外的空终止符填充数组的其余部分(复制后的剩余空间),这对于大型缓冲区来说可能很重要。它确实可以防止缓冲区溢出,但还有其他方法可以防止溢出。在我看来,最好避免使用整个函数系列。以上是关于正确填充字符指针的主要内容,如果未能解决你的问题,请参考以下文章