不寻常的字符串行为

时间:2016-09-18 10:42:20

标签: c++ c string

#include<stdio.h>
#include<iostream>
#include<cstring>
using namespace std;
int main(void)
{
    char a[10]="Rosewater";
    char b[3];

    int i=0;
    for(i=0;i<5;i++)
    {
        b[i]=a[i]; //1. does not throw an error
    }
    printf("%s\n%s\n",a,b);
}

输出

ewsewater        // value of a also changed

Rosewsewater      // unclear output

3 个答案:

答案 0 :(得分:1)

  

// 1。不会抛出错误

C C ++ 中没有边界检查,因为它只是暴露原始内存。

定义为未定义行为的内容。 这意味着(非常简短)标准没有指定程序中会发生什么,当指令产生未定义的行为时,任何事情都可能发生。

我建议您使用 C ++ (与 C 不同的语言)是使用std::vector类。 Here References

请注意,当您尝试访问超出范围的索引时,std::vector会产生未定义的行为。相反,使用方法at会抛出异常。

#include <vector>

int main(int argc, char* argv[]) {
  std::vector<char> a = {'a', 'b', 'c'};
  a.at(5);  // it will throw an exception
  return 0;
}

此外,如果你必须管理字符串,最方便的类是std::string

答案 1 :(得分:0)

访问分配的块之外的内存是未定义的行为。

-no-compile-examples -no-icu -opengl desktop -skip qtscript -nomake examples -nomake tests -skip qtwebengine -skip qtvirtualkeyboard -skip qtcharts -skip qtwebchannel -skip qtpurchasing -skip qtwayland -skip qtwebview -no-qml-debug

在此循环中,您最终会分配for(i=0;i<5;i++) { b[i]=a[i]; //1. does not throw an error } b[3]=a[3];

b[4]=a[4]b[3]是未分配的内存块。因此,访问它们是一种未定义的行为。

由于未定义的行为,可能会出现不可预测的结果。

根据标准:

  

可能的未定义行为包括完全忽略具有不可预测结果的情况,在转换或程序执行期间以环境特征(有或没有发出诊断消息)的文档方式执行,终止翻译或执行(发布诊断信息)。

修改 如有疑问关于细分错误

分段错误是一种特殊的错误,它是由访问“不属于你”的内存引起的。但反之则不然,即你不能说每当你访问未分配的内存时你都会遇到分段错误。

有些系统在没有内存保护的情况下运行,因此你无法判断一块内存是否真正属于你&#34;,因此不知道是否会发生分段错误,只保证未定义的行为。

答案 2 :(得分:-1)

char b[3]; // [X] [X] [NULL_CHAR] at this point

  int i=0;
  for(i=0;i<5;i++)
  {
     b[i]=a[i]; //1. does not throw an error
  }

所以基本上,当你= 3/4/5时,你的内存就会破坏。 这是未定义的行为。 如果你的程序没有那个记忆 - 它将是一个seg。故障。 但这只是一个运气问题,这个程序行为是出乎意料的。