首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调用isalpha导致分割故障

调用isalpha导致分割故障
EN

Stack Overflow用户
提问于 2018-05-28 10:57:30
回答 4查看 2.1K关注 0票数 10

我有以下程序,它会导致分段错误。

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(int argc, char *argv[])
{
    printf("TEST");

    for (int k=0; k<(strlen(argv[1])); k++)
    {
        if (!isalpha(argv[1])) {
            printf("Enter only alphabets!");
            return 1;
        }
    }

    return 0;
}

我发现是这条线导致了这个问题

代码语言:javascript
复制
if (!isalpha(argv[1])) {

而用argv[1]代替argv[1][k]解决了这一问题。

然而,我发现很奇怪的是,这个程序导致了一个分割错误,甚至没有打印TEST。我还期望isalpha函数不正确地检查指向argv[1]char*指针的下字节是否正确,但情况似乎并非如此。我有代码来检查参数的数量,但这里没有简单显示。

这里发生了什么事?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-05-28 11:13:51

一般来说,讨论为什么未定义的行为会导致这样或那样的结果是毫无意义的。

但是,尝试理解某些事情发生的原因并不有害,即使它超出了规范的范围。

isalpha的实现使用一个简单的数组来查找所有可能的unsigned char值。在这种情况下,作为参数传递的值被用作数组的索引。当一个真正的字符被限制为8位时,整数就不是了。该函数以一个int作为参数。这也是为了允许输入不适合于EOFunsigned char

如果您将像0x7239482342这样的地址传递到您的函数中,这远远超出了所述数组的末尾,当CPU试图使用该索引读取条目时,它会从世界边缘掉下来。;)

使用这样的地址调用isalpha是编译器在将指针转换为整数时应该发出一些警告的地方。你可能忽略了..。

可能包含检查有效参数的代码,但也可能只依赖于用户,而不是传递不应该传递的内容。

票数 19
EN

Stack Overflow用户

发布于 2018-05-28 11:37:12

  1. printf没有脸红
  2. 从指针到整数的隐式转换应该至少生成约束冲突的编译时诊断,从而产生了一个超出isalpha范围的数字。isalpha被实现为一个查找表,这意味着您的代码访问表超出了界限,因此没有定义行为。
  3. 您没有得到诊断信息的原因可能在一个方面,因为isalpha是如何作为宏实现的。在我使用Glibc 2.27-3 3ubuntu1 1的计算机上,isalpha被定义为定义isalpha(c) __isctype( (c),_ISalpha) # defined __isctype(c,type) \ ((*__ctype_b_loc ())(int) (C)&(无符号短int)类型)宏包含一个不幸的转换到int中,这将使您的错误安静下来!

在这么多人之后我发布这个答案的原因之一是,您没有修复代码,它仍然存在给定扩展字符和char被签名的未定义行为(在x86-32和x86-64上通常就是这种情况)。

isalpha的正确的论据是(unsigned char)argv[1][k]C11 7.4

在所有情况下,参数都是int,其值应表示为unsigned char或等于宏EOF的值。如果参数有任何其他值,则行为未定义.

票数 6
EN

Stack Overflow用户

发布于 2018-05-28 11:05:09

我觉得很奇怪的是,这个程序在没有打印测试的情况下导致分割错误。

printf不会立即打印,但它会写入时态缓冲区。如果要将字符串刷新到实际输出,则使用\n结束字符串。

而用argv1代替argv1解决了这一问题。

isalpha用于处理单个字符。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50564810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档