什么是C语言中的“总线错误10”?

48

以下是我的代码

#import <stdio.h>
#import <string.h>

int main(int argc, const char *argv[])
{
    char *str = "First string";
    char *str2 = "Second string";
    
    strcpy(str, str2);
    return 0;
}

代码编译时没有任何警告或错误,但在运行代码时出现了以下错误

Bus error: 10

我错过了什么?


1
好的,strlen(str)<strlen(str2) - user554546
47
大家都错过了 #import 吗?!! - Sangeeth Saravanaraj
4
@SangeethSaravanaraj 是的,我自己也不敢相信。哈哈 大家都错过了... - Mysticial
1
还有const char *argv[]这个在托管环境下不合法。你应该使用char *argv[] - ouah
9个回答

48

首先,您无法修改字符串字面值。这是未定义的行为。

要解决这个问题,您可以将 str 定义为本地数组:

char str[] = "First string";
现在,你将面临第二个问题,即 str 不足以容纳 str2。因此,您需要增加它的长度。否则,您将超出 str - 这也是未定义行为。
为了解决这个第二个问题,您需要将 str 至少设置为与 str2 一样长。或者动态分配它:
char *str2 = "Second string";
char *str = malloc(strlen(str2) + 1);  //  Allocate memory
//  Maybe check for NULL.

strcpy(str, str2);

//  Always remember to free it.
free(str);

还有更加优雅的方法可以做到这一点,涉及到C99中的可变长度数组(VLA)和栈分配,但我不会详细介绍它们,因为它们的使用有些问题。


正如@SangeethSaravanaraj在评论中指出的那样,大家都忽略了#import。应该使用#include

#include <stdio.h>
#include <string.h>

20
神秘的是,#import 在 C 语言中被 Clang 和 GCC 支持,并且是 Objective-C 的扩展。OP 的代码没有问题,因为它只添加了自动包含保护,没有其他内容。 - Richard J. Ross III
那是神秘的。 - Samie Bencherif

11

字符串没有分配空间。使用数组(或)指针和malloc()以及free()

除此之外

#import <stdio.h>
#import <string.h>
应该是这样的。
#include <stdio.h>
#include <string.h>

注意:

  • 使用 malloc() 分配的内容必须使用 free() 释放。
  • 对于长度为 n 的字符串,您需要分配 n + 1 个字节(最后一个字节是用于存储 \0 的)。

请参考下面的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    //char *str1 = "First string";
    char *str1 = "First string is a big string";
    char *str2 = NULL;

    if ((str2 = (char *) malloc(sizeof(char) * strlen(str1) + 1)) == NULL) {
        printf("unable to allocate memory \n");
        return -1; 
    }   

    strcpy(str2, str1);

    printf("str1 : %s \n", str1);
    printf("str2 : %s \n", str2);

    free(str2);
    return 0;
}

8

str2指向一个静态分配的常量字符数组。你不能写入或覆盖它。你需要通过*alloc函数族动态分配空间。


6

C中的字符串文字是不可修改的


6
你的代码尝试覆盖一个字符串常量,这是未定义行为。
有几种方法可以解决这个问题:
  1. 使用malloc()然后使用strcpy(),最后使用free()
  2. str变成一个数组,然后使用strcpy()
  3. 使用strdup()

6
这是因为str指向一个字符串常量,意味着一个不可变的字符串...但你试图通过复制来修改它。
注意:如果由于内存分配错误而导致错误,则在运行时会给出分段错误。但是,由于常量字符串修改或者您可以查看下面的更多详细信息,这种错误正在发生:
总线错误现在在x86上很少见,当处理器无法尝试所请求的内存访问时发生,通常包括:
- 使用具有不满足其对齐要求的地址的处理器指令。
段错误发生在访问不属于您的进程的内存时,它们非常常见,通常是以下原因:
- 使用已释放的指针。 - 使用未初始化的伪指针。 - 使用空指针。 - 溢出缓冲区。
更准确地说,这不是操纵指针本身会导致问题,而是访问它指向的内存(解除引用)。

2
让我解释一下为什么会出现“总线错误:10”的错误。
char *str1 = "First string";
// for this statement the memory will be allocated into the CODE/TEXT segment which is READ-ONLY

char *str2 = "Second string";
// for this statement the memory will be allocated into the CODE/TEXT segment which is READ-ONLY

strcpy(str1, str2);
// This function will copy the content from str2 into str1, this is not possible because you are try to perform READ WRITE operation inside the READ-ONLY segment.Which was the root cause 

如果您想进行字符串操作,请使用自动变量(堆栈段)或动态变量(堆段)。
Vasanth

1
每当您使用指针变量(星号)时,例如:

char *str = "First string";

您需要分配内存给它:

str = malloc(strlen(*str))


0

对我来说,没有提到的任何解决方案都不起作用,因为我找不到错误来自哪里。所以,我只是删除了我的node_modules并重新安装了它。然后错误消失了,我的代码又开始工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接