gpt4 book ai didi

c - C如何处理Buffer溢出?

转载 作者:太空宇宙 更新时间:2023-11-04 06:20:26 24 4
gpt4 key购买 nike

据我所知,在 C 语言中,有些数组可以在声明时指定长度。我想知道这些长度声明是否仅供其他程序员查看和理解使用,或者编译器是否可以通过禁止读取超过缓冲区长度的字符来保护代码。当我读入一个字符串时,它只是继续前进,并开始覆盖存储在我要读入的缓冲区之后声明的变量中的数据。有没有安全的方法来读入数据?

char arr[5];                                                                
char buff[5] = "cat";
printf("The buffer holds: %s\n", buff);
printf("Input a word to be held in \"arr\": ");

scanf("%s", arr);

printf("The array holds: %s\n", arr);
printf("The buffer holds: %s\n", buff);
printf("%c\n", arr[9]);

如果读入 arr 的字符串足够长,“cat”将被覆盖,并且所有编译标志似乎都没有做任何事情(我用 -Wextra -Wall -Werror -std=c99 编译)唯一提示的是瓦尔格林德。如何在 C 中编写安全数组代码?

最佳答案

从某种意义上说,C 语言本身既不会保护你也不会保护你不让你越界。更准确地说,C 编译器不需要执行边界检查,但允许这样做。 (很少有编译器利用该权限。非常默认情况下很少这样做。)

例如,如果你写:

int arr[10];
arr[20] = 42;

行为未定义。这并不意味着您的程序会崩溃。这并不意味着将或不会检测到错误。引用 ISO C 标准,

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

典型的 C 编译器可能会生成采用 arr 基地址的代码, 添加偏移量 20 * sizeof (int)到它,然后尝试存储 42在结果位置。如果没有显式或隐式检查,这可能会破坏其他一些数据结构,它可能会写入您的进程拥有但未用于任何其他用途的内存,或者它可能会终止您的程序。 (或者 #include <stdjoke.h> 它可能会让恶魔从你的 Nose 里飞出来。)

但是符合规范的 C 编译器可以添加代码来检查索引是否在 0 到 9 的范围内,如果不在范围内则采取一些明智的措施。 C 不禁止边界检查;它只是不需要它。

在这种特殊情况下,可以(但不是必需)在编译时检测到数组访问越界,因此编译器可以发出编译时警告。 (如果索引值直到运行时才知道,这是不可能的。)

最终,避免越界访问的责任落在了程序员身上。不要假设编译器会为您检查它——也不要假设它不会。

关于c - C如何处理Buffer溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36206724/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com