【问题标题】:I feel confusion about bus error in string (C)我对字符串 (C) 中的总线错误感到困惑
【发布时间】:2014-03-28 03:38:12
【问题描述】:

我对用 C 交换一个字符串中的两个字符感到困惑。 当我将它设置为数组时效果很好:

char strBase[8] = "acbdefg";

在这种情况下,我可以交换任何字符。 但是当我将它设置为字符串时会触发总线错误:

char *strBase = "acbdefg";

非常感谢任何人可以解释它或给我一些提示!

【问题讨论】:

  • char *strBase = "acbdefg" 是常量,不能修改。

标签: c string bus-error


【解决方案1】:

这里的区别在于

 char *strBase = "acbdefg"; 

acbdefg 放在内存的只读部分,并使strBase 成为指向它的指针,从而使对该内存的任何写入操作都是非法的。

它没有名字并且具有静态存储持续时间(意味着它在程序的整个生命周期中都存在);和 一个指向字符类型的变量,称为strBase,它使用该未命名的只读数组中的第一个字符的位置进行初始化。

在做的时候:

char strBase[8] = "acbdefg";

将文字字符串放入只读内存并将字符串复制到堆栈上新分配的内存。

所以这个数组是在内存中分配的,它的存在时间取决于声明出现的位置。如果声明在一个函数中,它将一直存在到声明它的块的末尾,并且几乎肯定会在堆栈上分配;如果它在函数之外,它可能会存储在“初始化数据段”中,当程序运行时,它会从可执行文件加载到可写内存中。

制作

strBase[0] = 'x';

合法的。

【讨论】:

    【解决方案2】:

    您的问题是内存分配问题之一。你需要空间来存储你的角色。当你写的时候:

    char strBase[8] = "acbdefg";
    

    您创建了自动存储(通常称为堆栈)并使用字符串对其进行了初始化。但是当你写的时候:

    char *strBase = "acbdefg";
    

    您创建了一个指针并将其指向一个常量字符串。编译器将其放入标记为只读的内存部分中。如果您尝试更改它,将导致内存访问冲突。

    相反,您可以执行以下操作:

    const char* strData = "acbdefg";
    int size = 1024;
    char *strBase = (char*)malloc(size);
    strncpy(strBase, strData, size);
    ProcessString(strBase);
    free(strBase);
    

    【讨论】:

      【解决方案3】:

      最可能的原因是

      char strBase[8] = "abcdefg";
      

      使编译器为一个八字符数组保留内存,并使用值“abcdefg\0”对其进行初始化。相比之下,

      char *strBase = "abcdefg";
      

      只为指针保留内存,用字符串的地址初始化。 "abcdefg" 是一个常量字符串,因此,编译器将它存储在一段被标记为只读的内存中。尝试修改只读内存会导致 CPU 故障。

      你的编译器应该在第二种情况下给你一个关于 const mismatch 的警告。或者,您的编译器可能具有更改常量字符串的只读性的设置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-19
        • 2015-03-13
        • 1970-01-01
        • 2021-01-27
        • 2021-12-05
        • 2013-07-28
        • 1970-01-01
        • 2014-07-23
        相关资源
        最近更新 更多