[Powered by Google Translate] [第5周]
[戴维·J·马兰 - 哈佛大学]
[这是CS50。 - CS50.TV]
>> 这是CS50，5周。
今天和这个星期，我们介绍了一点点取证的世界
的上下文中的问题设置4。
今天将是一个简短的演讲，因为在这里有一个特殊的事件后。
因此，我们将采取偷看，逗学生和家长的一致好评今天
一些的东西，是在地平线上。
>> 其中，截至周一，你将有一些更多的同学。
EDX，哈佛大学和麻省理工学院的“开放式课程网页”多新的网上倡议，
哈佛的校园（星期一），这意味着星期一上推出
最近的一次统计，你将有86,000额外的同学
将跟随着CS50的讲座和部分
和演练和习题集。
作为这项工作的一部分，你将成为成员的就职类的CS50，现在CS50x的。
作为这项工作的一部分，现在，知道会有一些的积极作为。
要为此做好准备，对于数量庞大的学生，
可以肯定地说，即使我们有108个转录因子和CA，
它不是最好的学生与教师的比例，一旦我们打80000的学生。
我们不打算分级这么多问题集手动，
所以本周推出的习题集将是CS50检查，
这将是一个命令行实用程序在设备
一次，你会得到你以后更新本周末。
您就可以运行命令，check50，你自身的pset，
，你会得到即时反馈，以您的程序是否正确或不正确
根据不同的设计规格，我们已经提供。
更多的是在问题集规范。
CS50x同学们将利用这一点。
>> 习题集4是所有约取证，
真的，这pset的灵感来自一些真实的东西
因此，当我在读研究生，我实习一段时间
米德尔塞克斯县地区检察官办公室从事法医工作
他们的领导取证调查。
这为我想我提到了几个星期过去，
是质量国家警察或其他人，
他们将放弃硬盘驱动器，CD和软盘之类的事情，比如，
然后的法医办公室的目标是要确定
是否有或没有某种形式的证据。
这是特别调查组，所以它是白领犯罪。
更令人不安的是什么形式的犯罪​​，涉及某种数字媒体的。
事实证明，没有那么多的人写一封电子邮件，说，“我做到了。”
所以很多时候，这些法医学搜索并没有打开所有的东西，水果，
但有时人们会写这样的邮件。
所以有时候，努力得到了回报。
>> 不过，导致这个法医pset中，我们将介绍在pset4位的图形。
你可能把这些东西是理所当然的 - JPEG格式，GIF和等 - 这些天。
但如果你真的仔细想想，图像，就像罗布的脸，
可以作为一个序列的点或像素建模。
在罗布的脸的情况下，有各种颜色，
我们开始看到各个点，否则称为像素，
一旦我们开始放大。
但是，如果我们简化了世界了一下，只是说，这是抢在黑色和白色，
代表黑色和白色，我们可以只使用二进制文件。
如果我们要使用二进制的1或0，我们可以表达这种相同的图像
这种模式的位Rob的笑脸。
11000011代表白，白，黑，黑，黑，黑，白，白。
因此，它不是一个巨大的飞跃，然后开始谈论精美图片，
的东西，你会看到在Facebook或用数码相机拍摄。
但可以肯定的，当涉及到颜色，你需要更多的比特。
在世界上的照片相当普遍的是使用1位颜色，
因为这建议，但24位色，你实际上得到数百万种颜色。
因此，作为的情况下，当我们放大罗布的眼睛上，
这是任何数以百万计的不同颜色的可能性。
因此，我们将介绍本习题集4，以及在演练中，
这将是今天下午3:30，而不是平常的下午2时30分，因为上周五的演讲在这里。
但是，视频将在网上像往常一样的明天。
>> 我们还将为您介绍另一种文件格式。
这是故意为了看起来吓人，
但是，这仅仅是一些文件的C结构。
事实证明，微软几年前捧红这种格式
，BMP的位图文件格式，这是一个超级简单的，丰富多彩的图形文件格式
用于相当长的一段时间，有时还在桌面上的壁纸。
如果你觉得回到了Windows XP和连绵起伏的丘陵和蓝色的天空，
这是典型的bmp或位图图像。
位图是我们的乐趣，因为他们有了更多的复杂性。
这是不是很简单，因为这格的0和1。
相反，你必须像一个头在一个文件的开始的东西。
因此，在其他的话，里面的bmp文件是一大堆的0和1，
但在那里有一些额外的“0”和“1。
而事实证明，我们可能已经多年理所当然的 -
任何文件格式的文件格式，如doc或xls或MP3，MP4，
你是熟悉的 - 它甚至意味着是一种文件格式，
因为在一天结束的时候，所有的这些文件，我们只有“0”和“1。
也许那些“0”和“1代表ABC通过ASCII或类似的，
但在一天结束的时候，它仍然只是“0”和“1。
因此，人类只是偶尔决定发明一种新的文件格式
他们规范的位模式，实际上的意思。
在这种情况下，这里的人谁设计的位图文件格式
说的第一个字节中的位图文件，有表示的偏移量为0，
有一些神秘命名的变量称为bfType，
这只是代表了位图文件的类型，这是什么类型的位图文件。
你或许可以推断出从第二行偏移2字节2号，
有图案的0和1，代表什么？事物的大小。
它从那里。
因此，在习题集4，你会走过一些事情。
我们会关心所有的人都没有好下场。
但是请注意，它开始变得有趣的周围字节54：rgbtBlue，绿色和红色。
如果你曾经听说过的缩写，RGB - 红，绿，蓝 - 这是一个参考
因为事实证明，你可以画的彩虹的所有颜色
与红色，蓝色和绿色的某种组合。
而事实上，在房间里的父母可能还记得最早的投影机。
这些天，你只看到一个明亮的光出来的镜头，
但早在一天，你有红色的镜片，蓝色镜片，绿色镜片，
和一起，他们的目的是在屏幕上，并形成了丰富多彩的画面。
很多时候，中学和高中有那些镜头
有一点点歪，所以你看到双重或三重影像。
但他的想法。你有红色，绿色和蓝色光画一幅画。
在电脑上使用相同的原则。
>> 所以之间的挑战，那么对你来说，在问题设置都将是几件事情。
一个是调整图像的大小，图案中的0和1，
找出其中的“0”和“1块代表什么这样的结构在，
然后找出如何复制的像素 - 红军，蓝军，果岭 -
内，这样当最初的图片看起来是这样的，
它可能看起来像这样，而不是之后。
在其他的挑战将是，你会交由法医的图像
一个实际的文件从数码相机。
该相机，曾几何时，是一大堆的照片。
问题是我们不小心删除或已损坏的图像以某种方式。
不好的事情发生的数码相机。
所以我们很快就复制了所有为你关闭该卡的“0”和“1，
保存他们都在一个大文件，然后我们会交给你的问题​​集4
所以，你可以写一个程序，在C恢复所有的这些JPEG文件，理想。
而事实证明，JPEG文件，即使它们是有点复杂的文件格式 -
他们要复杂得多，这笑脸 -
事实证明，每一个JPEG相同的模式0和1开始。
所以，最终，一个while循环或循环或类似的，
在此法医图像，你可以遍历所有的“0”和“1，
每次你看到的特殊的模式，集规范中定义的问题，
在这里，你可以假设，具有非常高的概率，开始的JPEG。
而一旦当你发现相同的模式一定数量的字节
或千字节或兆字节后，你可以假设这里是第二JPEG，
我把照片后的第一个。
让我停止阅读，第一个文件，开始写这个新的，
输出你的程序pset4的是多达50个JPEG文件。
而且，如果它不是50 JPEG文件，你有一点的循环。
如果你有无限多的JPEG文件，你有一个无限循环。
所以，这也将是一个相当常见的情况。
所以，这就是在地平线上。
>> 测验0在我们的身后，实现按我的电子邮件，总是有乡亲谁都是幸福的，
排序的中性，悲伤周围测验的0时间。
请你伸出我的头，你自己的TF TF Zamyla，
的CA，你知道，如果你想讨论如何去。
>> 因此，要在这里留下深刻印象的父母在房间里，什么是的CS50库吗？
[笑声]好工作。
的CS50库？是啊。 >> [学生]：这是一个预先写好的代码集[听不清]
好，好。
这是一个预先写好的代码集，我们的工作人员写的，我们提供给你，
提供了一些常用的功能，
这样的东西让我一个字符串，给我一个int - 此处列出的所有的功能。
>> 从现在起，我们开始真正把这些训练车轮。
我们将开始从你带走一个字符串，
这使人想起什么实际的数据类型只是一个代名词？ >> [多学生的char *。
CHAR *。对于父母来说，那可能是[呼呼的声音。这是很好的。
我们将开始看到在屏幕上更因为我们从我们的词汇中删除字符串的char *，
至少当涉及到实际编写代码。
同样，我们将停止使用这些功能尽可能多
因为我们的程序将会变得更加复杂。
而不是仅仅写一个提示，闪烁坐在那里，
等待用户输入一些东西，你会得到你输入的其他地方。
例如，你会得到他们的本地硬盘驱动器上的一系列位。
相反，你会得到他们在未来的网络连接，
一些网站的地方。
>> 因此，让我们剥开这层第一次拉CS50电器
这个文件称为cs50.h，＃你已经包括了几个星期，
但让我们看到这里面有什么。
在蓝色的文件的顶部是一大堆的意见：
保修信息和许可。
这是一个共同的范式软件
这些天，因为很多软件是所谓的开源的，
这意味着有人已经写好的代码和自由
不只是运行和使用，但实际读取和修改，并融入自己的工作。
所以，这就是你一直在使用开源软件，尽管在一个非常小的形式。
不过，如果我向下滚动过去的意见，我们将开始看到一些比较熟悉的东西。
在顶部，cs50.h文件包括一大堆的头文件的通知。
最重要的这些，我们还没有见过，但一个是熟悉的。
这些我们看到，尽管是短暂的，迄今？ >> [学生]标准库。
是啊，标准库。 stdlib.h中的malloc。
一旦我们开始谈论动态内存分配，
我们会回来下周开始，包括该文件。
事实证明，布尔和真假实际上并不存在在C本身
除非你有这个文件在这里。
我们已经好几个星期，得到了包括stdbool.h
这样，您可以使用这个概念的一个布尔值，true或false。
没有这一点，你就必须假的排序，并使用int
只是任意假设0是假的，1是真实的。
如果我们进一步向下滚动，在这里我们定义一个字符串。
事实证明，我们已经说过，这颗星在哪里并不重要。
你甚至可以有空间的限制。
我们这学期一直在推动它，因为这明确
明星做的类型，
但实现一样普遍，如果没有一点更为常见，
是把它放在那里，但在功能上是一样的东西。
但现在如果我们进一步读下来，让我们来看看在调用getInt
因为我们使用之前，也许别的学期。
下面是调用getInt。这是什么？ >> [学生]的原型。 >>这仅仅是一个原型。
通常情况下，我们的原型在我们的顶部。c文件，
但你也可以把原型的头文件，。h文件中，像这样的在这里
所以，当你写一些功能，你希望其他人能够使用，
而这恰恰与CS50库的情况下，
你不仅实现你的功能的东西像cs50.c，
也把原型不是在该文件的顶部，但在一个头文件的顶部。
然后，头文件是什么样的朋友和同事，包括
在自己的代码中使用＃include。
所以这个时候，你已经包括所有这些原型，
在文件的开头，但通过这有效地＃include机制，
这基本上是复制和粘贴文件到您自己的。
下面是一些比较详细的文档。
我们几乎是理所当然的调用getInt得到一个int，
但事实证明，有一些角落的情况下。
如果用户键入的数字太大了，一百万的三次方，
，只是不能装进一个int？什么是预期的行为吗？
理想的情况下，它是可预测的。
因此，在这种情况下，如果你真正阅读印刷精美，
实际上，你会看到，如果该行不能被读取，这将返回INT_MAX。
我们从来没有提到这一点，但其资本额的基础上，它可能是什么？
[学生]恒定的。 >>这是一个常数。
这可能是这些头文件在一个声明，它的一些特殊的常量
了更高的文件，并INT_MAX大概就像大约2亿美元，
的想法是，因为我们需要以某种方式表明的东西出了问题，
是的，我们有我们所掌握的4十亿的数字：-2亿元到2亿元，给予或采取。
那么，什么是常见的编程是你偷的只是这些数字，
也许0，也许2十亿，也许-2亿元，
所以你用一个可能的值，这样就可以提交到世界
，如果出现错误，我会回到这个超级大的价值。
但你不希望用户输入一些神秘的像234 ...，一个非常大的数字。
您概括它，而不是为一个常数。
所以，真的，如果你是肛门过去几周里，任何时候你叫调用getInt，
你应该被检查，如果条件做了INT_MAX的用户类型，
或者，更具体地说，调用getInt返回INT_MAX，因为如果它这样做，
这实际上意味着他们没有键入它。在这种情况下，出现了错误。
因此，这是通常被称为一个标记值，这只是意味着什么。
>> 现在，让我们变成的。c文件。
C文件已经存在了一段时间的家电。
而事实上，该设备有预编译的到的事情，我们称为目标代码，
但它只是对你重要，那是因为系统知道
在这种情况下，它是：该设备。
让我们现在向下滚动到调用getInt，看看如何调用getInt一直致力于这一切。
在这里，我们从之前也有类似的评论。
让我放大的代码部分。
我们调用getInt如下。
它不接受任何输入。
它返回一个int值，而（真），所以我们有一个故意的无限循环，
但想必大家会打破这个以某种方式或在此返回。
>> 让我们来看看它是如何工作的。
我们似乎在这个循环内的第一线，使用GetString 166。
现在，这是很好的做法，因为在什么情况下可能的GetString返回
特殊的关键字NULL？ >> [学生]如果出现错误。
如果出现错误。会出什么差错，当你调用类似的GetString？
是啊。 >> [学生] malloc失败给它的整数。
是啊。也许malloc失败。
引擎盖下方的某个地方，GetString的调用malloc分配内存，
这使得计算机能够存储所有的字符
进入键盘的用户类型。
假设用户得到了很多的空闲时间，多类型的，例如，
甚至有超过2亿美元，比电脑更多的字符的字符RAM。
GetString的是，以表示对你。
即使这是一个超级，超级罕见的角落的情况，
它以某种方式来处理这个问题，
等GetString时，如果我们回去，并阅读其说明文件，确实在事实上，返回NULL。
所以，现在如果GetString的失败，返回NULL，调用getInt是要失败的返回INT_MAX
就像一个哨兵。这些都只是人的约定。
你会知道这是唯一的办法是通过阅读文档。
>> 让我们向下滚动到其中int实际上是得到了。
如果我向下滚动一些，在170行，我们有上述评论，这些线路。
我们声明一个int，N，和一个char，C，然后这个新的功能，在172
你们中的一些偶然发现之前，sscanf的。
这代表的字符串scanf函数。
换句话说，给我一个字符串，我将扫描件信息感兴趣。
这是什么意思呢？
假设，我在键盘上输入，从字面上看，123，然后按Enter键。
123时，由GetString返回的数据类型是什么？ >> [学生]字符串。
这显然​​是一个字符串，对不对？我有一个字符串。
所以123是真的，报价引文结束，123 \ 0在它的结束。
这不是一个整数。这不是一个数字。它看起来像一个数字，但它实际上不是。
那么，是什么调用getInt有什么关系？
从左向右扫描该字符串 - 123 \ 0 - ，并以某种方式转换成一个实际的整数。
你可以计算出如何做到这一点。
如果你觉得回到了pset2，你大概有点生气了舒适与凯撒
或维琼内尔，所以你可以遍历字符串，你可以转换为整数的字符。
不过，赫克说，这是一个大量的工作。
sscanf的，做一个这样的函数，你为什么不叫？
，所以sscanf的预计参数 - 在这种情况下，称为线，它是一个字符串。
然后，您可以指定在引号中，非常类似于printf，你希望看到在这个字符串中。
我在这里所说的是我希望看到一个十进制数，也许一个字符。
我们会看到为什么是这样的情况下，在短短的时刻。
事实证明，这个符号是现在回忆的东西，我们开始谈论
只是在一个星期前。
什么是＆N＆C为我们做吗？ >> [学生] n和c的地址。
是啊。它给我的地址n和c的地址。为什么这很重要？
你知道，在C的功能，您可以随时返回一个值或没有价值。
您可以返回一个int，一个字符串，一个浮点数，字符，什么的，或者你可以返回void，
但你可以只返回一件事最大限度。
但在这里我们要sscanf的我，也许返回一个int，一个十进制数，
和一个字符，在某一时刻，我会解释为什么字符。
您可以有效地sscanf函数返回两件事情，但是这只是不可能在C.
您可以解决的，通过两个地址
因为只要你交给一个功能的两个地址，
该函数有什么可以做呢？ >> [学生]发表到这些地址。
它可以写入到这些地址。
您可以使用恒星运转，去那里，每个地址。
用于改变的变量的值，它的排序这个后门的机制，但很常见的
以上只是一个地方 - 在这种情况下，两个。
请注意，我检查== 1，然后返回n如果这样做，其实，计算结果为true。
所以，这是怎么回事呢？从技术上说，我们真的要发生在调用getInt是这样的。
我们要分析，可以这么说，我们要读取的字符串 - 报价 - 享有的123 -
如果它看起来像有一个数字，则我们告诉sscanf的做
在这个变量n对我来说，这个数字 - 123 - 。
那么为什么我居然有这样的呢？
sscanf的说你可能会得到一个字符在这里的作用是什么？
[听不见的学生反应] >> A小数点实际上可以工作。
让我们认为，想了一会儿。还有什么呢？
[学生]：这可能是NULL。 >>良好的思想。这可能是空字符。
在这种情况下，它实际上不是。是啊。 >> [学生] ASCII。
ASCII。还是让我进一步概括。
％c有错误检查。
我们不希望这是之后的字符数，
但让我做的是以下。
事实证明，sscanf的，除了这里存储在n和c的值，在这个例子中，
什么也没有返回的变量值英寸
所以，如果你只输入了123，那么只有％是怎么回事相匹配，
只有n个被存储的值，如123，
没有东西在c。
C保持一个垃圾值，可以这么说 -
垃圾，因为它从来没有被初始化为某个值。
因此，在这种情况下，sscanf函数返回1，因为我填充这些指针，
在这种情况下，伟大的，我有一个int，所以我释放线释放内存
实际上，GetString的分配，然后我返回n，
否则，如果你有没有想过，重试来自，它来自这里。
这样的话，与此相反，I型123foo - 只是一些随机序列的文本 -
，sscanf的是要看到数字，数字，数，f，
和它打算把n的123，它打算把在c在f，然后返回2。
因此，我们有，只是使用的基本定义，sscanf的行为，一个很简单的方法 -
以及，复杂，乍一看，但在年底的一天相当简单的机制 -
说的是有一个int，如果是的话，是我发现的唯一吗？
这里的空白是故意的。
如果你读了sscanf的文档，它会告诉你，如果你有一块空白
在开端或末端，sscanf的太将允许用户，无论什么原因，
按空格键123，这将是合法的。
你不会在用户喊叫，只是因为他们打空格键
在开始或结束，这只是一个小更方便用户使用。
>> 如有任何问题，然后调用getInt？是啊。 >> [学生]如果你只是把一个char是什么？
这个问题问得好。
如果你刚刚输入的一个字符像f，并按下回车键没有输入123，该怎么办？
你认为这行代码的行为将是什么？
[听不见的学生反应]
是啊，所以sscanf的可以覆盖这一点，因为在这种情况下，它不会填写N或C。
这是怎么回事，而不是返回0，在这种情况下，我也赶上该方案
我想是因为预期值1。
我只想要一个只有一件事来填补。这个问题问得好。
>> 其他人吗？好的。
>> 让我们通过在这里的所有的功能，
但是，这似乎是可能的剩余权益的GetString
因为事实证明调用getInt GetFloat，的GetDouble，GetLongLong
所有平底船了很多的功能，GetString的。
因此，让我们来看看他是如何在这里实现。
这一个看起来有点复杂，但它使用相同的基本原理
我们开始谈论上周。
GetString时，它没有参数，在这里每虚空
它返回一个字符串，我显然我声明了字符串缓冲。
我真的不知道那是什么要用于还，但我们会看到。
它看起来像能力是由默认的0。
不太清楚这是怎么回事，不知道n是要用于还
但现在它变得更有趣一些。
在243行，我们声明了一个int，C。
这是一个愚蠢的细节。
char是8位，8位可以存储多少不同的值吗？ >> [学生256。 >> 256。
现在的问题是，如果你想有256个不同的ASCII字符，其中有
如果你认为 - 这是不是记住的东西。
但是，如果你觉得回到了那个大的ASCII图表，我们有几个星期前，
在这种情况下，有128或256个ASCII字符。
我们使用所有的模式，“0”和“1了。
这是一个问题，如果你想成为能够检测到一个错误
因为如果你已经使用了256个值，为你的角色，
你真的不提前计划，因为现在你也没有办法说，
这是不是一个合法的字符，这是一些错误的信息。
所以，世界是他们最大的价值，像一个int，
所以，你有一个疯狂的数字，32位，4亿的可能值
所以，你可以简单的使用基本上是257，
1，其中有一些特殊的含义为错误。
>> 因此，让我们来看看它是如何工作的。
在246行，我有这样大的while循环，调用fgetc函数，
F含义的文件，所以GETC，然后标准输入。
事实证明，这仅仅是说从键盘读取输入更精确的方法。
标准输入方式键盘，标准输出屏幕，
和标准错误，我们会看到pset4的，就是说屏幕
而是一种特殊的屏幕部分，因此，它不是与实际产量混为一谈
你打算打印。但更多的是在未来。
因此fgetc函数从键盘读取一个字符，并将其存储在那里？
将它保存在c。
然后再检查 - 所以我只是用一些布尔连词 -
检查它不等于“ - \ n，所以在用户按下回车键，我们要停止在这一点上，
循环结束 - 我们还需要检查的特殊常量EOF，
如果你知道或猜测，什么是代表？ >> [学生]：文件的末尾。 >>末页的文件。
这是一种荒谬的，因为如果我在键盘上打字，
真的没有参与这一文件，
但是，这仅仅是排序的通用术语，用来指
，没有别的来自人类的手指。
EOF - 文件结束。
顺便说一句，如果你曾经打你的键盘控制D，不，你还没有 -
你按下Control C - D发送控制这个特殊的常数，称为EOF。
所以，现在我们只是有一些动态内存分配。
>> 所以，如果第（n + 1>容量）。现在我将解释N。
N是目前究竟有多少字节在缓冲区中，
你目前正在建设的字符串从用户。
如果你有比你有更多的字符在缓冲区中的缓冲能力，
直观地，我们需要做的是什么，然后分配更多的容量。
所以我要掠过这里的算术只专注于这个功能。
你知道什么是malloc的，或至少是一般熟悉。
什么realloc的猜测。 >> [学生]添加内存。
这不是很新增记忆体。它重新分配的内存如下。
如果在字符串的结尾还是有空间，该内存以使您更
比原来给你，然后你会得到额外的内存。
所以，你可以不断地将字符串的字符背靠背背靠背。
但是，如果是这样的情况并非如此，因为你等太久
和一些随机得到了一屁股在内存中
但有额外的内存在这儿，没关系。
realloc是要为你做所有的繁重，
移动您已经阅读因而在离这里不远的字符串，把它放在那里，
然后给你一些更多的在这一点上跑道。
>> 因此，一挥手，让我说，是做什么的GetString
是它的一个小缓冲区，也许一个单一的字符，
如果两个字符的用户类型，GetString的最终调用realloc的，并说
一个字符是不够的，给我两个字符。
然后，如果你读通过逻辑的循环，它会说
用户输入3个字符;给我，而不是2 4个字符，
然后给我，然后给我16位和32位。
事实上，我的能力增加一倍
意味着该缓冲区不会生长缓慢，它的超快速增长。
可能是什么的优势是什么？
为什么我的缓冲区大小增加一倍
即使用户可能只需要一个额外的字符从键盘吗？
[听不见的学生回应] >>那是什么？ >> [学生]你不经常必须增加。
没错。您不必经常增长。
而这仅仅是种对冲你的赌注在这里，
的想法是，你不希望调用realloc的有很多，因为它往往是缓慢的。
任何时候，你问的操作系统的内存，
你很快就会看到在未来的习题集，它往往需要一定的时间。
因此，最大限度地减少，大量的时间，即使你浪费了一些空间，
往往是一个很好的事情。
>> 但是，如果我们读通过的GetString在这里的最后一部分 -
重新认识这里的每一行是不那么重要的今天 -
注意，它最终再次调用malloc
它分配完全一样，因为它需要多少个字节的字符串
然后扔掉致电免费过大的缓冲区
如果它确实得到了太多的时间翻了一倍。
因此，在短，这是多么的GetString已工作时间。
它所做的就是读取一个字符的时候，一而再，再而三，
每次它需要一些额外的内存，它要求操作系统
通过调用realloc的。
>> 有什么问题吗？好的。
>> 的攻击。
现在，我们理解指针，或者至少是越来越熟悉指针，
让我们考虑如何在整个世界开始崩溃
如果你不太捍卫对对抗性用户，
人们正试图攻入你的系统，
人谁是试图窃取您的软件绕过一些注册码
否则，他们可能有输入英寸
>> 在这个例子来看看这里，这是C代码的底部，有一个main函数的
调用一个函数foo。又是什么呢传递给foo？
[学生]一个参数。 >> [马兰]的单个参数。
因此，ARGV [1]，这意味着用户在命令行中输入的第一个字
后a.out或其他程序调用。
所以foo的顶部需要一个char *。但char *是什么？ >> [学生]一个字符串。
[马兰]一个字符串，因此在这里没有什么新东西。
该字符串是任意被称为酒吧。
在这里，字符c [12];类的半技术性的英语，这条线是在做什么？
[学生]的数组 - >>阵？ >> [学生]字符。 >>字符。
给我一个阵列为12个字符。因此，我们可以称之为一个缓冲。
它在技术上被称为C，但程序中的缓冲区仅仅意味着一堆的空间
你可以把一些东西英寸
然后，最后，memcpy的，我们还没有使用过的，但你可能已经猜到它做什么。
它的内存复制。它有什么作用呢？
显然复制酒吧，它的输入，到c的长度吧。
但有一个错误在这里。 >> [学生]您需要的sizeof字符。 “好了。
从技术上讲，我们真的应该做的strlen（条）* sizeof（char）的）的。这是正确的。
但是，在这里的最坏的情况下，让我们假定that's -
好吧。然后有两个错误。
大小（字符））;
让我们使这一点更广泛。
所以现在仍然是一个错误，这是什么？ >> [听不见的学生反应]
检查什么呢？ >> [学生]检查是否为NULL。
一般应检查是否为NULL，因为不好的事情发生
当指针为NULL，因为你可能最终会去那里，
你应该不会去提领的星算为NULL。
所以这是很好的。而我们做什么？从逻辑上讲，在这里有一个缺陷。
[学生]检查，如果argc> = 2。
因此，检查，如果argc> = 2。好了，所以在这个程序有三个错误这里。
我们现在会检查，如果用户实际键入任何东西到argv [1]。好。
那么什么是第三个错误吗？是啊。 >> [学生] C可能没有足够大。
好。我们检查一个场景。
隐式检查，请不要复制更多的内存比将超过该长度的酒吧。
因此，如果字符串用户输入的长度为10个字符，
这是说只复制10个字符。没关系。
但是，如果用户键入20个字符的字一个字的提示一样吗？
这是说拷贝20个字符酒吧变成了什么？
C，否则被称为我们的缓冲区，这意味着你只是写数据
8个字节，你没有自己的位置，
你并不拥有它们在这个意义上，你永远不分配。
因此，这是一般人都知道的缓冲区溢出攻击缓冲区溢出攻击。
在这个意义上，它是一个攻击，如果用户或程序的调用你的函数
这样做恶意，实际情况下，实际上可能是相当糟糕的。
>> 因此，让我们来看看这张照片。
此图片代表你的内存堆栈。
回想一下，每次你调用一个函数，你这个小的堆栈帧
然后另一个，然后另一个和另一个。
因此，到目前为止，我们只是一种抽象的这些矩形
在黑板上，或在屏幕上这里。
但是，如果我们放大这些矩形，当你调用一个函数foo，
事实证明，更重要的是在栈上，框架内的在该矩形
比是x和y，a和b，就像我们谈论交换。
事实证明，有一些低级别的细节，其中包括返回地址。
因此，原来当主调用foo，主要有告知富
main（）的地址是在计算机的内存中
因为否则，尽快foo的完成，在这种情况下，在这里，执行
一旦你达到这个封闭的大括号结束时的foo，
富不知道如何赫克控制的程序是应该去吗？
事实证明，这个问题的答案是在这个红色矩形。
这是一个指针，它是电脑临时存储
所谓的堆叠上的主地址，以便尽快为foo执行完成，
电脑知道在哪里和什么线主要回去。
保存的帧指针涉及此同样。
CHAR *酒吧代表着什么？
现在这个蓝色的部分是foo的框架。什么是吧？
酒吧的foo函数的参数。
所以，现在我们又回到熟悉的画面在排序。
还有更多的东西，并在屏幕上的干扰，
但这种淡蓝色的部分恰恰是我们一直在画在黑板上
类似交换。这是为foo的框架。
唯一在它现在是吧，这是此参数。
还有什么应该是在堆栈中，根据此代码在这里？
[学生]字符c [12]。 >> [马兰字符c [12]。
我们也应该看到，12平方的内存分配给一个变​​量名为c，
而事实上，我们也有在屏幕上。
最顶端的是c [0]，然后这张图的作者
没有理会绘制所有的平方，但确实有12有
因为，如果你看一下在右下角，C [11]如果从0数是12这样的字节。
但这里的问题。
在哪个方向是C成长？
自上而下的，如果它开始的顶部和底部生长的排序。
它看起来并不像我们给自己多跑道在这里。
我们画种自己陷入了困境，
C [11]是正确的，对吧，这是对保存的帧指针，
这是正确的，对返回地址。有没有更多的空间。
那么，有什么含义，然后如果你搞砸了
您尝试读取20字节到12个字节的缓冲区？
这8个额外的字节哪里去了？ >> [学生]内 -
一切里面，其中有一些是超级重要的。
和最重要的事情，可能是那里的红色框，返回地址，
因为假设你是意外或adversarially的覆盖这4个字节，
该指针的地址，不只是垃圾，但有一些
发生这种情况表示在内存中的实际地址。
有何重要意义，逻辑吗？ >> [学生]函数将返回一个不同的地方。
没错。
当foo回报率和点击率，大括号，程序将继续进行
返回到主，它会返回的地址是在这红色框。
>> 在绕过软件登记的情况下，
什么如果返回到地址的功能，通常被称为
后，你支付的软件，输入你的注册码？
您可以按招的电脑不会在这里，而是在这里。
或者，如果你真的很聪明，对手实际上可以输入在键盘上，例如，
而不是实际的单词，而不是20个字符，但假设他或她居然类型
一些字符表示代码。
它不会是C代码，它实际上是字符
代表二进制机器代码，“0”和“1。
但是，假如他们足够聪明，要做到这一点，
以某种方式粘贴到GetString的的提示东西，基本上是编译后的代码，
最后4个字节，返回地址覆盖。
请问您的地址，输入怎么办？
它实际上是存储在这个红色矩形的缓冲区的第一个字节的地址。
所以，你必须是真聪明，这是一个很大的试验和错误不好的人，在那里，
但如果你能有多大，这个缓冲区
最后几个字节的输入您提供的程序
发生在开始您的缓冲区的地址，你可以做到这一点。
如果我们通常所说的招呼，\ 0，这就是在缓冲区。
但是，如果我们更聪明，我们填补了这一缓冲，我们将统称叫什么攻击代码 -
AAA，攻击，攻击，攻击 - 这是只是做了一件坏事，
如果你真的很聪明，会发生什么情况，你可能做到这一点。
在这里的红色框是一个数字序列 - 80，C0，35，08。
请注意，相匹配的数字在这里。
它以相反的顺序，但其他一些时间。
请注意，这个返回地址被故意改变
相同的地址，而不是主要的地址。
因此，如果坏家伙是超级聪明，他或她将要包括在该攻击代码
像删除所有用户的文件或复制的密码
或创建一个用户帐户，然后我就可以登录到 - 在所有事情。
>> 这是危险的力量C.
因为你必须通过指针存取记忆体
因此，你可以写任何你想要到一台计算机的内存中，
你可以让一台计算机做任何你想要的
简单的跳跃，在它自己的内存空间。
所以到今天这么多的程序和这么多的网站被攻破
归结到人趁着这个。
这可能看起来像一个超级复杂的攻击，但它并不总是这种方式开始。
现实情况是，什么不好的人通常会做的是，
无论它是一个程序，在命令行或GUI程序或网站，
你刚开始提供废话。
您键入一个真正的大词在搜索字段并按下回车键，
你就等着看，如果网站崩溃
或者你就等着看，如果程序体现了一些错误信息
因为如果你幸运的坏家伙，你提供一些疯狂的输入
，导致程序崩溃，这意味着程序员没有预料到你的错误行为，
这意味着你可以有足够的精力，足够的试验和错误，
如何发动更精确的攻击。
因此，安全的一部分，不只是完全避免这些攻击
但检测，实际上是在寻找日志
并看到什么疯狂的输入输入到你的网站的人，
什么样的搜索字词输入到您的网站的人
在一定的缓冲溢出的希望。
而这一切都可以归结为简单的基础知识，什么是一个数组
这是什么意思，分配和使用内存。
>> 相关的，然后是这样的。
我们只是看了一眼里面的硬盘驱动器。
你还记得一两个星期前，当你将文件拖到回收站或垃圾桶，
发生了什么？ >> [学生]没有。 “绝对没有，对不对？
最后，如​​果你运行的磁盘空间不足，
Windows或Mac OS将开始为您删除的文件。
但是，如果你拖动的东西在那里，这不是在所有的安全。
你的室友或朋友或家人做的就是双击，瞧，
所有的粗略的，您尝试删除的文件。
我们大多数人至少知道，你必须右击或控制点击
清空垃圾桶或类似的东西。
但是，即使这样，它不太做的伎俩
因为当你有你的硬盘驱动器上的文件
一些Word文件或某些JPEG，这代表您的硬盘驱动器，
让我们说这个条子在这里表示该文件，
它是由一大堆的0和1。
会发生什么事时，你不仅该文件拖动到垃圾桶或回收站
但也空吗？排序无关。
这不是绝对没有。
现在是不是真的发生在此表的形式，因为少了一些。
因此，有一些种类的数据库或表内的一台计算机的内存
在本质上具有文件的名称，一列一列文件的位置，
这可能是123，只是一个随机位置。
因此，我们可能有一些如x.jpeg和地点123。
然后会发生什么当你真正清空你的回收站？
这消失。
但不会消失的是0和1。
>> 那么，有什么然后连接到pset4的吗？
好了，与pset4，只是因为我们不小心删掉了紧凑型闪存卡
所有这些照片，或只是因为它的坏运气成为损坏
并不意味着“0”和“1”是不是仍然存在。
也许他们几个人都失去了，因为有东西损坏
在这个意义上，一些“0”变成1秒和1秒变成0。
不好的事情都可能发生，因为软件bug或有缺陷的硬件。
但许多这些位，也许他们甚至100％，是仍然存在。
这只是电脑或相机，不知道去哪里JPEG1开始
和JPEG2开始。
但是，如果你作为程序员，知道这些JPEG文件是位精明的
它们看起来像什么，这样你就可以分析“0”和“1和JPEG，JPEG，
你可以写一个程序，基本上只是一个while循环
，恢复这些文件的每个人。
因此，教训是安全地删除您的文件
如果你想完全避免这种情况。是。
>> [学生]为什么说在您的计算机上
你有更多的内存比你以前吗？
比你以前有更多的内存 - >> [学生]更多的可用内存。
哦。这个问题问得好。
那么为什么你的计算机后清空垃圾桶告诉你
你有更多的自由空间比你以前吗？
简单地说，因为它是在撒谎。
技术上，你有更多的空间，因为现在你所说的
该文件一旦你可以把其他的东西。
但是，这并不意味着这些位去，
和，这并不意味着正在被改变的比特都为0，例如，
为保护您的利益。
相反，如果你安全地删除文件或物理损坏设备，
这确实是有时解决这一问题的唯一途径。
>> 那么，为什么我们不离开上，半吓人的，我们将看到你在周一。
[掌声]
>> [CS50.TV]