【问题标题】:Computer Memory Allocation for Duplicate Inputs重复输入的计算机内存分配
【发布时间】:2020-06-08 02:35:11
【问题描述】:

我正在学习 CS 简介(CS50,哈佛),我们正在学习 C 中的类型声明。当我们声明一个变量并分配一个类型时,计算机会分配特定数量的位/字节(1 个字节用于 char , int 为 4 个字节,双精度为 8 个字节等...)。

例如,如果我们声明字符串“EMMA”,我们将使用 5 个字节,每个“char”使用 1 个字节,\0 空字节额外使用 1 个字节。

好吧,我想知道为什么 2 M 被分配单独的字节。计算机不能利用当前在内存中占用空间的字符或整数,并在它想要重用它时引用该特定插槽吗?

希望对此事进行一些教育(不要太深入,因为我对这个领域还很陌生)。

编辑:将一些位固定为字节——我的错

【问题讨论】:

  • 例如,如果我们声明字符串“EMMA”,我们使用 5 位;你的意思是5个字节,关于你的问题,看看Data structure alignment
  • 那么一个引用必须至少有一个地址可以找到真正的值——并且地址需要 4 或 8 个字节(32 位/64 位系统)
  • 1 byte for char
  • 基本上你想知道为什么它不能只存储“EMA”并记住使用M两次。但是它怎么会记得使用 M 两次呢?
  • 这样想:为什么在一张纸上写“Hallo”而不是“Halo”时要写两个L?如果你跳过一个 L,你会节省纸张空间。除了现在这个词有不同的含义。因此,您必须通过在纸上写下以下内容来解释这一点:“在下面的文本中,将'Halo'替换为'Hallo'”。而且该文本占用的纸张空间比 L 多得多。

标签: c memory types cs50


【解决方案1】:

1 位用于 char,4 字节用于 int,8 字节用于双精度等...

这些是通用值,但它们取决于架构(根据this answer,现在甚至还在销售每字节 9 位的架构)。

计算机不能利用当前在内存中占用空间的字符或整数,并在它想要重用它时引用那个特定的插槽吗?

虽然这个想法在理论上肯定是可行的,但实际上对于字符等简单数据来说开销太大了:一个字符通常是一个字节。

如果我们要建立一个系统,在其中我们为字符值分配内存并仅从字符串中引用它,那么字符串将由一系列元素组成,这些元素将用于存储应该存在的字符:在 C 语言中,这将是一个指针(您会在课程中的某个时候遇到它们),通常是 4 或 8 字节长(32 或 64 位)。假设您使用 32 位指针,您将使用 24 字节的内存以这种复杂的方式存储字符串,而不是使用更简单的方法的 5 字节(扩展 this answer,您将需要更多元数据才能在程序执行期间正确修改字符串)。

然而,在以下几种情况下确实存在存储一大块数据并多次引用它的想法:

  • 虚拟内存(如果你做操作系统开发你会遇到这个),这里使用copy-on-write
  • 高级语言(如 C++)
  • 实现写时复制功能的文件系统,如BTRFS
  • 一些备份系统(如 borgrsync)会删除它们存储的文件/块的重复数据
  • Facebook 的 zstandard compression algorithm,其中 dictionnary of small common chunks 的数据用于提高压缩率和速度

在存储大量数据的此类设置中,存储数据一次并多次引用它同时缩短复制时间所需的信息的相对大小值得增加复杂性。

【讨论】:

  • 哇哦!如果我错了,请纠正我,但基本上你的意思是,对于这个特定的例子,这样的内存引用自动化实际上会比它的帮助更多,对吧?在这么大的数据集中知道我想到的问题被考虑了,这也很酷。迫不及待地想在课程中前进并了解更多信息,感谢您的澄清! :)
  • 你是对的:对于少量数据,它会。但是,在切换到这样一个系统之前,没有绝对的数据量应该有多大(但对于字符来说绝对不值得)。
【解决方案2】:

例如,如果我们声明字符串“EMMA”,我们使用 5 位

我确定您说的是 5 字节而不是 5 位。

好吧,我想知道为什么 2 M 被分配单独的位。不能 计算机利用当前占用空间的字符或整数 内存并在它想要重用时引用该特定插槽?

指向“槽”的指针通常占用 4 或 8 个字节。所以花8个字节指向一个只占用一个字节的对象是没有意义的

此外,"EMMA" 是一个由相邻字节组成的字符数组。所以数组的所有元素都具有相同的类型和相应的大小。

编译器可以通过避免重复的字符串文字来减少内存使用。例如,它可以将相同的字符串文字存储为一个字符串文字。这取决于编译器选项。

因此,如果在程序中相同的字符串文字出现两次,例如在这些语句中

char *s = malloc( sizeof( "EMMA" ) );
strcpy( s, "EMMA" );

那么编译器只能存储字符串文字的一份副本。

【讨论】:

    【解决方案3】:

    编译器不应该是代码/程序,而是做最少的事情,它必须执行任务,以便程序员易于理解和操作,换句话说,它必须是通用。

    作为一名程序员,您可以让您的程序以建议的方式保存数据,但这不是通用的。

    例如-我正在为我的学校创建一个数据库,我输入了错误的名称,现在我想更改“EMMA”中的第二个“m”,如果系统按照您的建议工作,这将很麻烦。

    如果需要,希望进一步澄清。 :)

    【讨论】:

      猜你喜欢
      • 2020-01-12
      • 1970-01-01
      • 2016-10-08
      • 1970-01-01
      • 2015-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多