正确填充字符指针

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";

【讨论】:

另见:strcatstrchrstrncpystrncat【参考方案4】:

为该字符串分配内存后,您可以使用strcpy 来填充它:

strcpy(s, "abcdef");

【讨论】:

strncpy 通常被宣传为更安全的strcpy,但复制 c 字符串也很糟糕。如果您的数组太小,它不保证空终止。它还用额外的空终止符填充数组的其余部分(复制后的剩余空间),这对于大型缓冲区来说可能很重要。它确实可以防止缓冲区溢出,但还有其他方法可以防止溢出。在我看来,最好避免使用整个函数系列。

以上是关于正确填充字符指针的主要内容,如果未能解决你的问题,请参考以下文章

cout输出字符指针

memset 不使用指向字符的指针

字符数组和字符指针的差别

按要求编写字符界面(算法初阶最小值和最大值)填充每个节点的下一个右侧节点指针(树深度优先搜索)最大矩形(栈数组)

如何正确地为字符串“数组”动态分配内存

字符串类型数组的指针运算,C++如何处理这个?