C 在边界外访问阵列有多危险?

C 在边界外访问阵列有多危险?,c,arrays,memory,C,Arrays,Memory,在数组边界之外访问它有多危险(在C中)?有时,我从数组外部读取数据(我现在了解,然后访问程序的其他部分或甚至其他部分使用的内存),或者我试图将值设置为数组外部的索引。程序有时崩溃,但有时只是运行,只会产生意外的结果 现在我想知道的是,这到底有多危险?如果它破坏了我的程序,那也没那么糟糕。另一方面,如果它破坏了我程序之外的东西,因为我不知何故设法访问了一些完全不相关的内存,那么我想这是非常糟糕的。 我读了很多“任何事情都有可能发生”,“你的硬盘可能会变成粉红色,独角兽可能会在你的窗口下唱歌”,这些

在数组边界之外访问它有多危险(在C中)?有时,我从数组外部读取数据(我现在了解,然后访问程序的其他部分或甚至其他部分使用的内存),或者我试图将值设置为数组外部的索引。程序有时崩溃,但有时只是运行,只会产生意外的结果

现在我想知道的是,这到底有多危险?如果它破坏了我的程序,那也没那么糟糕。另一方面,如果它破坏了我程序之外的东西,因为我不知何故设法访问了一些完全不相关的内存,那么我想这是非常糟糕的。 我读了很多“任何事情都有可能发生”,“你的硬盘可能会变成粉红色,独角兽可能会在你的窗口下唱歌”,这些都很好,但真正的危险是什么呢

我的问题是:

  • 从数组外部读取值会损坏任何东西吗 除了我的节目?我可以想象,仅仅是看着事物 不会改变任何事情,或者它会改变“最后一次”吗 我碰巧接触到的文件的“已打开”属性
  • 设置数组之外的值是否会损坏除我之外的任何东西 节目?由此 我想这是可能的 任何内存位置,都没有安全保证
  • 我现在在XCode中运行我的小程序。是吗 在我的程序无法保护的地方提供一些额外的保护 超出自己的记忆范围?它会伤害XCode吗
  • 关于如何安全地运行我固有的错误代码,有什么建议吗

  • 我使用OSX 10.7,Xcode 4.6。

    除了你自己的程序之外,我不认为你会破坏任何东西,在最坏的情况下,你会尝试从一个内存地址读或写,该地址对应于内核没有分配给你的进程的一个页面,生成适当的异常并被杀死(我是说,你的进程).

    不以root用户或任何其他特权用户身份运行程序不会损害您的任何系统,因此通常这可能是一个好主意

    通过将数据写入某个随机内存位置,您不会直接“损坏”计算机上运行的任何其他程序,因为每个进程都在自己的内存空间中运行

    如果您试图访问任何未分配给进程的内存,操作系统将以分段错误停止程序的执行

    因此,直接(不以root用户身份运行,也不直接访问/dev/mem等文件),您的程序不会干扰操作系统上运行的任何其他程序

    然而,也许这就是你所听到的关于危险的说法,如果你不小心将随机数据写入随机内存位置,你肯定会损坏任何你能损坏的东西

    例如,您的程序可能希望删除由存储在程序中某处的文件名给定的特定文件。如果您无意中覆盖了文件名的存储位置,您可能会删除一个完全不同的文件。

    您写:

    我读了很多“任何事情都有可能发生”的书,“分割可能是最重要的。” 最坏的问题','你的硬盘可能会变成粉红色,独角兽可能会 在你的窗户下唱歌,这很好,但什么是真的 危险

    让我们这样说:装枪。把它指向窗外,没有任何特别的目标和火力。危险是什么

    问题是你不知道。如果您的代码覆盖了使您的程序崩溃的内容,您就可以了,因为它会将程序停止到定义的状态。但是,如果它没有崩溃,那么问题就开始出现。哪些资源在您的程序的控制之下,以及它会对它们做什么?哪些资源可能会受到您的程序的控制,以及它会对它们产生什么影响?我知道至少有一个主要问题是由这种溢出引起的。问题出在一个看似毫无意义的统计函数中,它弄乱了生产数据库中一些不相关的转换表。结果是事后进行了一些非常昂贵的清理。事实上,如果这个问题已经格式化了硬盘,它会更便宜,也更容易处理。。。换言之:粉红色的独角兽可能是你最小的问题


    您的操作系统将保护您的想法是乐观的。如果可能,尽量避免写越界。Objective-C中的NSArray被分配了一个特定的内存块。超出数组的边界意味着您将访问未分配给数组的内存。这意味着:

  • 这个内存可以有任何价值。根据您的数据类型,无法知道数据是否有效
  • 此内存可能包含敏感信息,如私钥或其他用户凭据
  • 内存地址可能无效或受保护
  • 内存的值可能会发生变化,因为它正被另一个程序或线程访问
  • 其他东西使用内存地址空间,例如内存映射端口
  • 将数据写入未知内存地址可能会导致程序崩溃,覆盖操作系统内存空间,并通常导致太阳内部爆炸

  • 从程序的角度来看,您总是希望知道代码何时超出数组的边界。这可能会导致返回未知值,导致应用程序崩溃或提供无效数据。

    一般来说,当今的操作系统(不管怎样,还是流行的操作系统)使用虚拟内存管理器在受保护的内存区域中运行所有应用程序。事实证明,简单地读取或写入已分配/分配给进程的区域之外的真实空间中的位置(就其本身而言)并不十分容易

    直接回答:

  • 读取几乎不会直接损坏另一个进程,但是如果您碰巧读取了用于加密、解密或验证程序的密钥值/p,则它可能会间接损坏一个进程
    char arr1[2][8];
    char arr2[4];
    int test1(int n)
    {
      arr1[1][0] = 1;
      for (int i=0; i<n; i++) arr1[0][i] = arr2[i];      
      return arr1[1][0];
    }
    int test2(int ofs, int n)
    {
      arr1[1][0] = 1;
      for (int i=0; i<n; i++) *(arr1[0]+i) = arr2[i];      
      return arr1[1][0];
    }