【问题标题】:C function with pointers work on one computer, and doesn't work on another带指针的 C 函数在一台计算机上工作,在另一台计算机上不起作用
【发布时间】:2015-01-13 14:08:22
【问题描述】:
#include <stdio.h>
void swap (int *a, int *b)
 {
    int *tmp;
    *tmp = *a;
    *a = *b;
    *b = *tmp;
 }

int main ()
{
 int x = 5;
 int y = 7;
 swap (&x,&y);
 printf ("\n x = %d \n y = %d \n",x,y);
}

我正在使用代码块,但这段代码不起作用,我不明白为什么......在一台计算机上它运行良好,但在另一台计算机上它根本无法运行。 有什么帮助吗? 提前致谢。

【问题讨论】:

  • *tmp = *a; 你没有收到警告吗?
  • 它没有坏,这可能是什么原因?也许硬盘上的坏扇区?感谢您的回答。
  • 不,我是在讽刺,你的程序因为 Gopi 暴露的原因而无法工作,你正在取消引用一个无效的指针,这是未定义的行为,这恰恰意味着它行为不会一致,因此例如跨计算机的行为是不同的。
  • 我认为 Gopi aleady 已经充分回答了您的问题,但可以节省时间的一件事就是将 tmp 设为整数,而不是指针。你所要做的就是删除一些*

标签: c function pointers swap


【解决方案1】:
int tmp;
tmp = *a;
*a = *b;
*b = tmp;

您需要的是一个变量tmp 来存储值,而不是一个指针*tmp

下面的代码确实是一种糟糕的方法,但是

int *tmp = malloc(sizeof(int));

    *tmp = *a;
    *a = *b;
    *b = *tmp; 

完成后请释放内存使用

free(tmp);

【讨论】:

  • 你可以解释一下发生了什么,这会提高正确答案的质量。
  • 它的工作原理是这样的,但我想在 tmp 上使用指针。我知道它是这样工作的,在我尝试使用指针之前我已经这样做了。
  • @АлександарМакрагић 为什么要弯腰才能完成这件简单的事情?
  • @АлександарМакрагић 如果您真的想这样做,请检查编辑
  • @iharob 是的,先生已经处理好了 :)
【解决方案2】:

Gopi 已经更正了您的代码 - 添加到上一个答案 - 我认为这对新手来说是很好的了解信息:

第 4.1 节规定:

a 的左值 (3.10) 非函数,非数组类型 T 可以是 转换为右值。如果 T 是一个 不完整的类型,一个程序 需要这种转换是 格式不正确。如果对象 左值引用不是类型的对象 T 并且不是类型的对象 派生自 T,或 如果对象是 未初始化,一个程序 需要这种转换有 未定义的行为。如果 T 是一个 非类类型,右值的类型 是 T 的 cv 不合格版本。 否则,右值的类型是 T.

当您尝试取消引用和未初始化的指针时,行为未定义。未定义意味着任何事情都可能发生 - 无法保证。因此,您可以在不同的环境中获得不同的行为。

来自维基Making pointers safer

没有分配任何地址的指针称为野指针。任何使用此类未初始化指针的尝试都可能导致意外行为,因为初始值不是有效地址,或者因为使用它可能会损坏程序的其他部分。结果通常是分段错误、存储冲突或野分支(如果用作函数指针或分支地址)。

你在这里做了什么:

int *tmp;
*tmp = *a;

是你创建了一个指向 int 的指针,它没有指向任何东西 - 基本上它包含一些垃圾值(甚至可能是你的密码 - 谁知道)。

【讨论】:

  • 他的错误是如此基本,以至于这么多信息只会让他更加困惑。
  • was so basic UB是新手最容易犯的错误。
  • @JonatanGoebel 我同意 al-Acme 的观点,这种错误很常见,如果有人想学习一些东西,他们应该通过阅读而不是反复试验来完成。
  • @iharob 我并没有不同意他所说的,只是他发布的方式。他对答案所做的编辑应该是第一件事,然后他可以插入参考,而不是相反。
  • *tmp points to some adress that does not exist? - 也有可能或可以指向某个有效地址没有保证And if I want to use pointers like I did I need to somehow initialize tmp? So that *tmp points to something that exists?是的。
【解决方案3】:

您的错误是使用了未初始化的内存。始终在使用指针之前为其分配内存。接下来,不要忘记在完成后释放分配的内存。

另外,您应该在main() 函数的末尾添加return 0;

如果您不介意第二意见,请查看以下代码。

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

void swap (int *a, int *b)
{
        int *tmp = malloc(sizeof(*tmp));
        *tmp = *a;
        *a = *b;
        *b = *tmp;
        free(tmp);
}

int main ()
{
        int x = 5;
        int y = 7;
        swap (&x,&y);
        printf ("\n x = %d \n y = %d \n",x,y);
        return 0;
}

【讨论】:

  • 如果我很粗鲁,请原谅我,但不要匆忙投反对票,请花点时间提高问答的质量,比如提到return 0的要求[我是没有看到这一点有点惊讶,即使作为 commentsidenote]。
  • c99 标准 (5.1.2.2.3) 说:reaching the } that terminates the main function returns a value of 0.,所以你不需要在 main 函数的末尾加上 return 0;
  • @mch 我从来没有说过它是errorproblem。我提到的只是质量。这是一个很好的做法。希望我没有被误解。 :-)
  • 在这种情况下,您应该写“您应该添加return 0;...”而不是“您需要...”
  • @mch 点。现在我正在路上。请你编辑一下好吗?
【解决方案4】:

如果你想使用指针,虽然它根本没有任何意义

void swap(int *a, int *b)
{
    int tmp[1];

    *tmp = *a;
    *a   = *b;
    *b   = *tmp;
}

这里的tmp严格来说并不是一个指针,但是你可以在它上面使用*间接操作符。

或者

void swap(int *a, int *b)
{
    int value = *a;
    int *tmp  = &value;

    *tmp = *a;
    *a   = *b;
    *b   = *tmp;
}

或者您可以使用 malloc,正如 Gopi 已经指出的那样。

【讨论】:

    【解决方案5】:

    如果你想使用指针,那么请使用指针:

    #include <stdio.h>
    
    void swap (int ** ppx, int ** ppy)
     {
       int * p = *ppx;
       *ppx = *ppy;
       *ppy = p;
     }
    
    int main (void)
    {
      int x = 5;
      int y = 7;
      int * px = &x;
      int * py = &y;
    
      printf ("\nx = %d\ny = %d\n", *px, *py);
    
      swap (&px, &py);
    
      printf ("\nx = %d\ny = %d\n", *px, *py);
    
      return 0;
    }
    

    结果:

    x = 5
    y = 7
    
    x = 7
    y = 5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      相关资源
      最近更新 更多