【发布时间】:2015-01-03 18:32:22
【问题描述】:
我正在试验指针。我最初创建了一个指向字符的指针,并为该指针分配了 2 个字节的大小。然后我运行循环直到 1000 分配一些值。当我尝试打印字符串时,它会给我一整套已分配的值。
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char *a = (char *)malloc(2);
for (int i=0;i<10;i++)
a[i]='a';
cout<<a<<"\t"<<strlen(a)<<"\n";
return 0;
}
输出如下
aaaaaaaaaa 10
我在 C 和 C++ 中运行相同的代码。他们给了我同样的结果。
首先想到的是,由于我使用了指针,所以 a[3] 的意思是 *(&a + 3): 这可以解释为什么我能够为该位置分配一个值。但是,即使我只为 String 分配了两个字节的内存,为什么我的字符串长度会发生变化?为什么编译器的行为方式不同?屏幕后面是什么?
操作系统:OS X 10.10.0 编译器:gcc ||克++ 架构:64 位架构
Edit1:这与段错误无关。
Edit2: 如果是因为 strlen 读取直到遇到空终止符。我没有在字符串的末尾声明它。
【问题讨论】:
-
好吧,这与它为什么不崩溃无关!这是关于为什么要更改字符串的大小?
-
strlen只计算连续字符(字节),直到遇到空终止符。它不知道 malloc 或您为任何东西分配的空间大小。因此,因为您在连续的内存区域中写入了 10 个“a”,strlen将至少计为 10。malloc分配的内存大小从未改变。你只是在做超出记忆范围的读写操作。 -
@TheUndeadFish 在 C 或 C++ 中,我们显式声明字符串的结尾。这将是矛盾的。
-
我不明白你的意思。您分配了特定大小的内存,但随后写了过去。 C 和 C++ 不会阻止您做这些事情。实际上,一个程序的整个内存空间可以被认为是一个大数组。 C/C++ 在此之上强加了一组规则和想法,但是他们也希望您(程序员)遵循这些规则。当您违反这些规则时(例如通过写入超过分配内存的末尾),您可能会得到意想不到的结果。
-
@TheUndeadFish 感谢您回来。只是留给编译器的规则!我相信还有更多。我不能接受那个。谢谢你的朋友。
标签: c++ c string pointers memory-management