c - 为什么这会导致核心转储?
问题描述
#include <ctype.h>
#include <stdio.h>
int atoi(char *s);
int main()
{
printf("%d\n", atoi("123"));
}
int atoi(char *s)
{
int i;
while (isspace(*s))
s++;
int sign = (*s == '-') ? -1 : 1;
/* same mistake for passing pointer to isdigit, but will not cause CORE DUMP */
// isdigit(s), s++;// this will not lead to core dump
// return -1;
/* */
/* I know s is a pointer, but I don't quite understand why code above will not and code below will */
if (!isdigit(s))
s++;
return -1;
/* code here will cause CORE DUMP instead of an comile-time error */
for (i = 0; *s && isdigit(s); s++)
i = i * 10 + (*s - '0');
return i * sign;
}
当我在 's' 之前不小心弄错了 * 运算符时,我得到了“分段错误(核心转储)”,然后我得到了这个令人困惑的错误。为什么“(!isdigit(s))”导致核心转储,而“isdigit(s),s ++;” 将不会。
解决方案
来自isdigit [强调添加]
如果 ch的值不能表示为 unsigned char且不等于 EOF,则行为未定义。
来自isdigit [强调添加]
c 参数是一个 int,应用程序应确保其值是可表示为无符号字符的字符或等于宏 EOF 的值。如果参数有任何其他值,则行为是 undefined。
https://godbolt.org/z/PEnc8cW6T
未定义的行为包括它可能执行不正确(崩溃或默默地生成不正确的结果),或者它可能偶然地完全按照程序员的意图执行。
推荐阅读
- aws-lambda - amazon lex 聊天机器人可以接受图像作为输入吗?
- amazon-web-services - 如何使用 npm 包(如 activedirectory、ldapjs 或 ldap-client)访问 AWS Microsoft AD
- python - python中的dijkstra实现-输出并不总是正确的
- spring-mvc - 在 Controller 的 RequestMapping 中启用 ConditionalOnProperty
- google-apps-script - 使用云端硬盘搜索结果会导致迭代器错误
- python - tf.image.sample_distorted_bounding_box 中“bounding_boxes”和“min_object_covered”的功能?
- android - 如何根据条件显示布局?
- nginx - nginx配置与位置具有不同的根
- android - 后台定位服务奥利奥
- python - 使用 ftplib python 访问 ftp 目录