【问题标题】:An error when passing an array by reference to a function通过引用函数传递数组时出错
【发布时间】:2014-07-12 21:25:05
【问题描述】:

我正在尝试编写一个程序,将数组的反转放入另一个数组。所以,我做了一个函数来做相反的事情。并传递要按值反转的数组。并且该数组用于通过引用存储反向。但是当我运行程序时它崩溃了。

#include <stdio.h>
#include <conio.h>
#define size 50

void revarr (int num1[], int *num2)
{
    int i;
    for (i = 0; i<size; i++)
    {
     num2[3-1-i] = num1[i];
    }

}

int main()
{
    int num[] = {1,8,1};
    int reverse[3],x;
    revarr(num,reverse);
    for (x = 0; x<3; ++x)
        printf("%d ", reverse[x]);
    getch();
    return 0;
}

我该如何解决这个问题?

【问题讨论】:

  • 您将i 增加到49,此时num2[3-2-i] 将是num2[-47] -> 不允许负偏移
  • num2[3-1-i] 怎么回事?
  • 您可以通过在代码行之间放置一些打印语句来解决此问题,这样您就可以找出崩溃的位置。然后问自己“为什么那行代码会崩溃”,如果你不能解决这个问题,那么你可以来 SO 寻求答案。先做一些调查。

标签: c arrays


【解决方案1】:

导致崩溃的原因是未定义的行为。将数组传递给函数时,该数组衰减为该数组第一个元素的指针(内存地址)。好的,您仍然可以在指针上使用 [] 运算符,但您需要确保 a_ptr[123] 仍然有效且可访问的内存
如果不是什么都可能发生。这就是为什么它被称为未定义行为。

如果说reverse[0]的内存地址是0x04,而sizeof(int)是4,那么reverse[-1] = 123就等于写成:*((int *) 0) = 123;。这是教科书未定义的行为(取消引用 NULL 指针!)。
more on this matter

您正在访问您不拥有的内存,超出范围的内存:您的数组定义为 3 长,但您正在使用 size 宏(应该是大写,顺便说一句)循环,它是 50。这是不允许的,因此发生了崩溃。更改revarr 函数以采用第三个参数,指定要反转的数组的长度,并确保您传递的两个数组都足够大以容纳数据:

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

void rev_array(int *to, int *from, size_t max)
{//arrays decay into pointers
    int i,j;
    for (i=max-1, j=0;j<max;--i,++j)
        to[j] = from[i];
}
int main ( void )
{
    int i,
        reverse[3],
        num[] = {1,2,3};
    rev_array(reverse, num, 3);
    for(i=0;i<3;++i)
        printf("%d -> %d\n", num[i], reverse[i]);
    return EXIT_SUCCESS;
}

如您所见here,它运行良好。

当然,您可以使用sizeof 获取数组的大小,而不是对 3 进行硬编码(注意:sizeof 适用于数组,而不适用于指针! ):

rev_array(
    reverse,
    num,
    sizeof num/sizeof *num
    //or sizeof(num)/sizeof(num[0])
);

【讨论】:

    【解决方案2】:

    它没有崩溃,因为数组索引是负数。 num2[3-1-i] 归结为 *(num2+3-1-i) 这很好。它崩溃的原因是因为它正在访问内存的受保护区域,而操作系统不允许这样做。由于numreverse 分别分配了3 个整数,因此您将离开数组(在num1 中,索引大于2;在num2 中,索引小于0)并且您不要'不知道分配给你的内存之外是什么。如果它正在访问某个受保护的区域,它将崩溃。如果幸运的话,它可能不会崩溃。但你不应该这样做。正如其他人所说,将size更改为3就可以了。

    【讨论】:

      【解决方案3】:

      首先,C 中没有引用传递。
      其次,您通过指针传递两个数组。
      第三,要么将#define size 50 更改为#define size 3,要么将数组长度传递给您的函数,否则访问其边界之外的数组是错误的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-24
        • 2010-09-13
        • 1970-01-01
        • 2015-04-02
        • 2012-05-16
        • 1970-01-01
        • 2011-08-09
        相关资源
        最近更新 更多