2016-06-10 67 views
1

通过书本去的,第一COUT行应打印我哪里字符变量b的存储位置的地址,这似乎是为int变量的情况下太。但是第一个cout语句打印出一个奇数'dh ^#'而第二个语句正确打印了十六进制值' ox23fd68'。这是为什么发生?指针在C++中的字符

#include<iostream> 
    using namespace std; 

    int main() 
    { 
     char b='d'; 
     int a=10; 
     char *c=new char[10]; 
     c=&b; 
     int *e=&a; 
     cout<<"c: "<<c<<endl; 
     cout<<"e: "<<e; 
    } 
+0

提示:“靠书本”应该“”c:“'也打印一个地址? –

+3

这不是一个坏问题,但可能在别处回答。简单的答案是C++继承了C对'char *'的处理,可能是可打印的东西的集合。 –

+1

从哪些书你有这个想法? – molbdnilo

回答

3

其实这个程序有问题。有内存泄漏。

char *c=new char[10]; 
c=&b; 

这堆上分配10个字符,但随后的指针堆改写为可变b的地址。

char*被写入coutoperator<<然后它被认为是空终止的C字符串。由于b的地址已初始化为包含d的一个字符,因此op<<继续在堆栈上搜索以找到第一个空字符。看起来它是在几个字符后被发现的,因此dh^#被写入(d是变量b的值,其余的只是在第一个\0字符之前在堆栈上发现的一些随机字符)。

如果您想获取地址,请尝试使用static_cast<void*>(c)

我的例子:

int main() { 
    char *c; 
    char b = 'd'; 
    c = &b; 
    cout << c << ", " << static_cast<void*>(c) << endl; 
} 

的输出:

dÌÿÿ, 0xffffcc07 

参见 'd' 后的奇怪的字符。

我希望这可以帮助一下!

5

没有为const char*类型,不写地址的非过载构件operator<<(std::basic_ostream),而是(推定)C风格串1)。就你而言,由于你已经分配了单个字符的地址,因此没有终止符,因此没有有效的C风格字符串。该代码展示undefined behavior

int*的行为不同,因为没有针对指向int的指针的特殊处理,并且该语句按预期将该地址写入流。

如果你想获得该字符的地址,而不是使用一个static_cast

std::cout << static_cast<void*>(c) << std::endl; 


1) C风格的字符串是一个字符序列,由NUL字符终止('\0')。