动态分配字符数组的内存

dynamic allocating memory for char array

本文关键字:内存 数组 字符 动态分配      更新时间:2023-10-16

对下一个代码块有一些理解问题。

#include<iostream>
using namespace std;
int main() {
char *str = "hi";
char *p = new char[strlen(str) + 1];
for (int i = 0; *(str + i); i++)
*(p + i) = *(str + i);
cout << p << endl;
return 0;
}

结果如下:

hi═¤¤¤¤

当我使用调试器时,我可以看到我的p指向一个包含 10 或 15 个或其他一些符号的数组(取决于编译(,所以我在"hi"之后得到了额外的符号。但是,当我使用 strcpy(( 时:

#include<iostream>
using namespace std;
int main() {
char *str = "hi";
char *p = new char[strlen(str) + 1];
strcpy(p, str);
cout << p << endl;
return 0;
}

我得到的结果:

hi

那么,有人可以向我解释一下,为什么我用第一个程序示例得到这样的结果,以及如何重新设计它以获得像第二个示例一样的结果。 提前谢谢。

答案是在循环的停止条件下,即*(str + i)

for (int i = 0 ; *(str + i) ; i++)
*(p + i) = *(str + i);

请注意,表达式中没有比较运算符。当在需要逻辑条件的上下文中使用这样的表达式时,会隐式比较零,即*(str + i)的意思与*(str + i) != 0相同。

现在应该清楚为什么字符串保持未终止:循环在发现空终止符时停止,并且不会将其复制到目标字符串中。

做同样事情的一种稍微"神秘"的方式是将比较与作业相结合,就像K&R书所做的那样:

for (int i = 0 ; *(p + i) = *(str + i) ; i++)
;

现在,空测试在分配后进行,确保目标以空终止。

您没有将终止空字符添加到p

添加行

*(p + i) = '';

for循环之后。但是,为此,您必须在for循环之前声明i

int i = 0;
for (i = 0; *(str + i); i++)
*(p + i) = *(str + i);
*(p + i) = '';
cout << p << endl;

你忘了在第一个 exend 中用零终止字符串:

#include <cstddef>
#include <iostream>
int main()
{
char const *str = "hi";
std::size_t length = std::strlen(str);
char *p = new char[length + 1];
for (std::size_t i = 0; i < length; ++i)
p[i] = str[i];
str[length] = '';
std::cout << p << 'n';
delete[] p;
}

请注意:字符串文字是不可变的,因此它们应该用char const*s 指向。将对象大小保存在内存中或索引到其中的正确类型是std::size_t,而不是int。如果执行手动内存管理,则必须确保通过使用new获得的指针传递到delete以及将指针从new[]传递到delete[]来释放分配的内存。

不过,您不应该手动进行内存管理。使用像std::stringstd::vector这样的容器,或者至少像std::shared_ptr<>std::unique_ptr<>这样的智能指针。