【问题标题】:Getting bus error while adding ascii values to array characters. Why? (C) [duplicate]将 ascii 值添加到数组字符时出现总线错误。为什么? (C) [重复]
【发布时间】:2017-12-07 13:48:20
【问题描述】:
#include <stdio.h>

char    *ft_strupcase(char *str);

char    *ft_strupcase(char *str)
{
    int i;

    i = 0;
    while (str[i])
    {
        if (str[i] >= 'a' && str[i] <= 'z')
        {
             str[i] -= 32;
        }
        i++;
    }
    return (str);
}

int main(void)
{
    char *test = ft_strupcase("fdfFEhk");
    for (int k = 0; test[k] != '\0'; k++)
    {
        printf("%c", test[k]);
    }
    return (0);
}

预期的结果是打印传递给函数的字符串,全部用大写字母。相反,我得到一个总线错误。为什么以及如何解决这个问题?

【问题讨论】:

  • 你不能用字符串文字来做。见这里stackoverflow.com/questions/1614723/…
  • 不能修改常量...
  • 如果您使用调试器执行此程序,您会发现指令str[i] -= 32; 将在第一个while 循环周期引发分段错误。这是因为字符串"fdfFEhk" 是一个常数。在 Linux 或 Windows 等操作系统下,这是一个错误。如果您在 DOS 下使用此代码,它应该可以运行。
  • 它是same problem。你为什么不看那些答案?

标签: c string


【解决方案1】:

在您的ft_strupcase() 函数中,您尝试修改string literal 的内容。这会导致undefined behavior

引用标准,C11,第 §6.4.5/P7 章,字符串文字

[...] 如果程序试图修改这样的数组,行为是 未定义。

您收到的参数是字符串文字,您不能更改内容。为了避免,你必须要么

  • 将可修改的内存作为实际参数传递。
  • 在函数内部,创建一个块(需要注意生命周期,static 存储或通过内存分配器函数分配),复制内容,执行修改操作并返回地址。

【讨论】:

【解决方案2】:

这是未定义的行为,因为您正在使用 ft_strupcase 函数修改 string literal

将您的代码重写为:

char source[] = "fdfFEhk";
char *test = ft_strupcase(source);

现在您的字符串不再是 字符串文字,并且每次初始化 source 变量时都会复制到 RAM。因此,您已经定义了行为。

【讨论】:

  • 在@EatABagel 编写的代码中,问题在于他使用的字符串是常数,而不是UB(恕我直言)。
  • @SergioFormiggini 尝试修改常量是未定义的行为。
  • 在 DOS 下是可能的。我只是在搜索旧的 DOS 编译器,看看它是否会产生错误,但这是考古!!!我认为这不是未定义的,而是与此相关的。 BTW 不是修改常量的好风格。
  • @SergioFormiggini 仍然是未定义的行为。期间。
  • 该错误是由不接受您在声明为只读的内存区域上写入的 CPU 生成的。此行为不依赖于 C 语言。
猜你喜欢
  • 2012-09-10
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 2015-04-12
  • 2021-04-25
相关资源
最近更新 更多