【问题标题】:Cause of Sementation fault [duplicate]分段错误的原因[重复]
【发布时间】:2020-01-04 10:21:07
【问题描述】:

当我写这个程序的时候,遇到了分段错误

void swap(int *a,int *b){
    int *temp;
    *temp=*a;
    *a=*b;
    *b=*temp; }

但是当我分配一些内存时,没有出现分段错误

void swap(int *a,int *b){
    int *temp;
    temp = malloc(sizeof(int));
    if (temp == NULL)
      return;
    *temp=*a;
    *a=*b;
    *b=*temp;
    free(temp);
}

但这背后的原因是什么?

【问题讨论】:

  • 在第一个版本中,你认为temp指向什么?

标签: c


【解决方案1】:

你的代码应该是:

void swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

换句话说,在你的交换过程中,你真的想要一个整数值而不是一个指向整数的指针。

由于没有内存来支持您拥有的 temp 指针,并且它未初始化的事实意味着它指向某个随机位置,这是不好的。一旦你取消引用它以保存a 后面的值,你就会遇到段错误。在这个版本中,我们留出堆栈空间来存储一个整数(不是指向 1 的指针,而是一个实际的整数)。这意味着要留出内存来保存该值,因此我们可以毫无问题地将数据复制到其中并从中复制出来(只要您不尝试读取或写入超出预留的内容)。

顺便说一句,由编译器打开额外警告可能是个好主意。如果您使用 clang 或 gcc,我强烈建议您在编译命令行中添加 -Wall-Wextra。您应该考虑学习使用调试器,您可以在其中单步执行并查看实际发生的情况。

【讨论】:

    【解决方案2】:

    您只需要int 类型的临时内存位置。得到这个的easy 方法是声明temp 类型为int

    void swap(int *a,int *b){
        int temp;
        temp=*a;
        *a=*b;
        *b=temp; }
    

    您在第一个版本中所做的是使用 temp uninitialized,这是 C 程序可能出错的众多方式之一。分配给*temp 会读取temp 的值,以便在它指向的位置写入,但temp 没有特别设置为任何值。任何事情都有可能发生。

    在第二个版本中,您在使用之前设置了temp 的值,甚至将其设置为有效内存位置的地址以存储int,这样一切正常:

        temp = malloc(sizeof(int));
        if (temp == NULL)
          return;
    

    虽然如果您决定以这种方式编写函数,它可能会失败,因此它应该能够以某种方式向调用者指示它何时失败。一种方法是让它返回成功代码而不是void

    // returns -1 for failure, 0 for success
    int swap(int *a,int *b){
        int *temp;
        temp = malloc(sizeof(int));
        if (temp == NULL)
          return -1;
        *temp=*a;
        *a=*b;
        *b=*temp;
        free(temp);
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      分段错误意味着您的程序试图访问不允许访问的内存区域。 上面的代码中可能会出现分段的原因有很多。我认为由于 调用交换函数时不使用 & 符号。

      你应该使用swap(&arg1,&arg2);来调用交换函数。

      但在第二个代码中,您使用动态内存分配,它将内存分配给 RAM 中内存空闲的区域。所以没有分段错误。

      【讨论】:

      • 我认为 OP 在调用 swap 函数时正在使用 &,而在第一个示例中他们只是没有初始化 temp
      猜你喜欢
      • 2013-04-07
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多