【问题标题】:Integer variable's value changes after passing to a function in c++整数变量的值在传递给c ++中的函数后发生变化
【发布时间】:2018-03-31 13:22:01
【问题描述】:

我在下面给出的代码中的函数 func 中传递 int 变量 N 的值。但是在执行 func 之后,N 的值会发生变化。 我按值传递 N。有人可以帮帮我吗?为什么值会发生变化?

void sort_by_pivot(int ar[], int N, int p)
{
    int pivot = ar[p],temp;
    for(int i=0; i<p; i++)
    {
        while(ar[i]>pivot)
        {
            if(ar[i] > pivot)
            {
                ar[p] = ar[p-1];
                ar[p-1] = pivot;
                temp = ar[i];
                ar[i] = ar[p];
                ar[p] = temp;
                p--;
            }
        }
    }

    for(int i=p+1; i<N; i++)
    {
        while(ar[i]<pivot)
        {
            if(ar[i] < pivot && p<N)
            {
                ar[p] = ar[p+1];
                ar[p+1] = pivot;
                temp = ar[i];
                ar[i] = ar[p];
                ar[p] = temp;
                p++;
            }
        }
    }
}


int main()
{
    int ar[] = {5,9,2,6,1,4,3,7,8};

    int N = 9;
    int p = 4;

    printf("%d\n",N);
    sort_by_pivot(ar, N, p);

    printf("%d\n",N);
}

这是输出:

9
1

【问题讨论】:

  • 移动 int Nint p 到你的数组声明之前;我敢打赌你会得到不同的结果(使用你的编译器)。
  • 当我运行你的代码时,我得到 9 然后是一个段错误。
  • 顺便说一句:为什么不添加 const 说明符?
  • 您没有边界检查,并且在第二个循环中,p 变量将增加到超出实际数组的长度,从而导致内存损坏和未定义的行为。你的算法坏了。结束。
  • 这不是 SO 的问题。直到您阅读并应用了How to debug small programs 中的材料。您需要首先在这方面发挥自己的作用。只有这样,如果您不明白是什么导致了您发现的问题,您可以在这里提问,minimal reproducible example

标签: c++ variables segmentation-fault parameter-passing


【解决方案1】:

类似于所描述的问题是内存损坏的明确指示,即代码覆盖了一些它不拥有的内存。在这种情况下,它会覆盖main 中的N 的值。

问题是当您的排序函数达到 p=1 和 i=0 时。假设列表看起来像

{9, 1, ....}

这些行

            ar[p] = ar[p-1];
            ar[p-1] = pivot;

将列表更改为

{1, 9, ....}

那你就做

            temp = ar[i];
            ar[i] = ar[p];
            ar[p] = temp;
            p--;

所以列表(错误地)改回

{9, 1, ....}

而 p 变为 0。

因此,您将再执行一个循环,在其中写入ar[p-1],现在是ar[-1],即越界。

【讨论】:

  • 谢谢大佬!!!最佳答案和重点。
【解决方案2】:

你正在读写ar[p-1],此时 p 可以(在这种情况下)为零。在数组边界之外读取或写入是未定义的行为。

【讨论】:

  • 当 p 达到零时,while 循环将不会运行 bcoz,在这种情况下 ar[p] == pivot。无论如何,我只想知道为什么要在函数之外修改 N。
  • @Corvo: 1) p 在第一个 while 循环中达到 0,如果您不相信我打印出来。 2) 您不针对pivot 测试ar[p],您针对pivot 测试ar[i]。 3) 未定义的行为可以修改导致它的函数之外的变量——或者它想做的任何其他事情。
【解决方案3】:

你的算法不正确。

您正在跨越数组ar 的边界,这会破坏内存。您永远不会在while(ar[i]&gt;pivot)while(ar[i]&lt;pivot) 循环中检查索引p+1p-1 的值。如果p+1 &gt;= Np-1 &lt; 0 你有问题。

【讨论】:

  • ar 的类型为 int[9]N=9,所以 ar[N] 肯定是未定义的行为。
  • @Caninonos 感谢您的评论!接得好!已更正。
  • 当 p 达到零时,while 循环将不会运行 bcoz,在这种情况下 ar[p] == pivot。无论如何,我只想知道为什么要在函数之外修改 N。
  • @Corvo 您正在写超过ar[] 数组覆盖N 变量。 ar[]N 都位于堆栈上,很可能并排位于内存中。
猜你喜欢
  • 2013-09-20
  • 1970-01-01
  • 2019-10-29
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 2012-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多