首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >值过去指向C样式字符串的有效指针。

值过去指向C样式字符串的有效指针。
EN

Stack Overflow用户
提问于 2016-08-13 09:29:12
回答 4查看 88关注 0票数 4

我目前正在努力通过"C++入门“。在其中一个练习问题中,它提出:

下面的程序是做什么的?

代码语言:javascript
运行
复制
const char ca[] = { 'h', 'e', 'l', 'l', 'o' };

const char *cp = ca;

while (*cp)
{
    cout << *cp << endl;

    cp++;
}

我很高兴我理解*cp将继续是ca[]数组的最后一个字符,因为数组中没有空字符作为最后一个项。

这更多的是因为我自己的好奇心,是什么使时间循环成为错误的。它似乎总是在我的电脑上显示19个字符。0-4是hello字符串,5-11总是相同的,12-19随每次执行而改变.

代码语言:javascript
运行
复制
#include <iostream>

using namespace std;

int main( )
{
    const char ca[ ] = { 'h', 'e', 'l', 'l', 'o'/*, '\0'*/ };

    const char *cp = ca;

    int count = 0;

    while ( *cp )
    {
        // {counter} {object-pointed-to} {number-equivalent}
        cout << count << "\t" << *cp << "\t" << (int)*cp << endl;

        count++;
        cp++;
    }

    return 0;
}

问题:是什么导致while循环失效?为什么5-11总是同一个角色?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-08-13 10:45:07

因为对于语言来说,访问超出其界限的数组所发生的事情是没有定义的,如果您想了解发生了什么,您必须了解您的“平台”是如何工作的。

对于大多数编译器来说,您的内存可能是按如下方式排列的:

代码语言:javascript
运行
复制
|H|e|l|l|o|XXX|____cp___|__count__|

XXX是对齐8所必需的“填充字节”。编译器-in调试版本--通常用除0以外的固定值填充这些字节,这样才不会停止(这样您就可以发现它)。

cp是一个指向"H“的指针,它一个接一个地递增。它的值通常是进程本身中进程堆栈的地址映射。

这个地址通常有一个固定的前缀,并且随着嵌套调用的深入,偏移值也会增加。

由于指针的长度(可能)为8字节(最后4个字节放在第一个字节之前,因为x86处理器的枚举数较低),您得到的是一个打印出来的迭代:

  • 五个“你好”字
  • 三个填充字符(承认你是可以打印的)
  • 从堆栈开始的cp偏移量(总是相同的,因为main总是在与程序本身相同的位置)
  • 进程前缀的一部分(在每次调用时都会发生变化)

这个前缀可能在某个点包含一个"0“,从而终止循环。

请注意,-however这个解释是有意义的--对于为不同平台编译的产品代码,您无论如何都不能信任它,甚至可能是不同的编译器,因为它们管理变量的方式也可能不同。

票数 2
EN

Stack Overflow用户

发布于 2016-08-13 09:39:44

C++允许您通过一个过去的ca[4] (包含)创建指向ca[0]的指针。不过,您可以取消引用(即应用操作符*),仅通过ca[4]对指向ca[0]的指针进行引用;指向过去ca[4]的指针是不允许的。当您取消引用指针时,会发生什么是未定义的行为。程序可能产生任何数据,甚至崩溃。

现实中发生的事情更简单:指针只是一个进入内存的地址,因此取消引用会继续向程序传递数字。在某个时候,地址包含一个零字节。这是你的程序停止的时候。

您的数组在自动内存中分配。大多数编译器都使用CPU堆栈。字节5.20的内容很可能包括cpcount,因为编译器倾向于将局部变量放在一起。之间可能有一些填充,因为指针和int通常在可被4整除的地址对齐。当然,您不能指望任何这样的情况发生,因为其他编译器会采取不同的做法。

票数 3
EN

Stack Overflow用户

发布于 2016-08-13 09:36:20

重要的是要知道,您正在体验Undefined behavior。因此,无论您现在看到什么,当您使用不同的编译器或不同的编译器选项时,都可能会有所不同。

5-11上的“常量”值最能解释的原因是,您正在读取堆栈的一部分,而该部分每次都恰好具有相同的值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38931288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档