gpt4 book ai didi

c - 必须(应该)避免使用标准库中的哪些函数?

转载 作者:太空狗 更新时间:2023-10-29 16:15:23 25 4
gpt4 key购买 nike

我在 Stack Overflow 上读到一些 C 函数是“过时的”或“应该避免”。你能给我一些这种功能的例子以及原因吗?

这些功能有哪些替代方案?

我们可以安全地使用它们 - 有什么好的做法吗?

最佳答案

弃用的函数
不安全
此类函数的一个完美示例是 gets() ,因为无法告诉它目标缓冲区有多大。因此,任何使用gets() 读取输入的程序都有一个buffer overflow vulnerability .出于类似的原因,应该使用 strncpy()代替 strcpy()strncat()代替 strcat() .

还有更多的例子包括 tmpfile()mktemp()功能归因于 potential security issues with overwriting temporary files并且被更安全的 mkstemp() 取代功能。

不可重入
其他示例包括 gethostbyaddr()gethostbyname()它们是不可重入的(因此不能保证是线程安全的)并且已被可重入 getaddrinfo() 取代和 freeaddrinfo() .

您可能会注意到这里的一个模式......要么缺乏安全性(可能是因为没有在签名中包含足够的信息以可能安全地实现它)或不可重入是弃用的常见来源。

过时的,不可携带的
其他一些功能只是被弃用,因为它们重复了功能并且不像其他变体那样可移植。例如,bzero()不赞成使用 memset() .

线程安全和重入
您在帖子中询问了线程安全性和可重入性。有一点不同。如果一个函数不使用任何共享的、可变的状态,那么它就是可重入的。因此,例如,如果它需要的所有信息都传递到函数中,并且所需的任何缓冲区也传递到函数中(而不是由对函数的所有调用共享),则它是可重入的。这意味着不同的线程,通过使用独立的参数,不会有意外共享状态的风险。重入性是比线程安全更有力的保证。如果一个函数可以被多个线程同时使用,那么它就是线程安全的。一个函数是线程安全的,如果:

  • 它是可重入的(即它在调用之间不共享任何状态),或者:
  • 它是不可重入的,但它根据共享状态的需要使用同步/锁定。

  • 一般来说,在 Single UNIX SpecificationIEEE 1003.1 (即“POSIX”),任何不保证可重入的函数都不能保证是线程安全的。因此,换句话说,只有保证可重入的函数才能在多线程应用程序中可移植地使用(没有外部锁定)。然而,这并不意味着这些标准的实现不能选择使不可重入函数线程安全。例如,Linux 经常为不可重入函数添加同步,以增加线程安全性的保证(超出单一 UNIX 规范的保证)。

    字符串(和内存缓冲区,一般来说)
    您还询问了字符串/数组是否存在一些基本缺陷。有些人可能会争辩说情况确实如此,但我会争辩说不,该语言没有根本性缺陷。 C 和 C++ 要求您分别传递数组的长度/容量(它不像其他一些语言那样是“.length”属性)。这本身不是缺陷。任何 C 和 C++ 开发人员只需在需要时将长度作为参数传递即可编写正确的代码。问题是几个需要此信息的 API 未能将其指定为参数。或者假设将使用某些 MAX_BUFFER_SIZE 常量。此类 API 现在已被弃用,取而代之的是允许指定数组/缓冲区/字符串大小的替代 API。

    Scanf(回答你的最后一个问题)
    就个人而言,我使用 C++ iostreams 库(std::cin、std::cout、<< 和 >> 运算符、std::getline、std::istringstream、std::ostringstream 等),所以我不通常处理那个。但是,如果我被迫使用纯 C,我个人只会使用 fgetc()getchar()结合 strtol() , strtoul()等并手动解析内容,因为我不是可变参数或格式字符串的忠实粉丝。也就是说,据我所知, [f]scanf() 没有问题。 , [f]printf()等,只要您自己制作格式字符串,就不会传递任意格式字符串或允许将用户输入用作格式字符串,并且您使用 <inttypes.h> 中定义的格式宏。在适当的地方。 (注意, snprintf() 应该用来代替 sprintf() ,但这与未能指定目标缓冲区的大小而不是格式字符串的使用有关)。我还应该指出,在 C++ 中, boost::format提供类似 printf 的格式,没有可变参数。

    关于c - 必须(应该)避免使用标准库中的哪些函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2565727/

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