【问题标题】:Changing elements of an array by passing by reference to a function通过引用传递函数来更改数组的元素
【发布时间】:2018-10-25 06:39:16
【问题描述】:

我试图通过引用传递一个数组,并在 changeArray() 中更改数组中的值。我收到一条错误消息,指出“访问冲突写入位置 0x00000001”。我阅读了Changing array inside function in C 并使用了 Ryyker 的答案来实现我的预期结果(获得 x[]={1,1,1,1,1])但我得到了上述错误。这是我的代码:

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

int changeArray(int **a);

int main(void) {

    int *x[5] = { 1,5,4,3,1 };
    int *y[5] = { 1,5,4,3,1 };

    changeArray(&x);
    for (int z = 0; z <= 4; ++z) {
        printf_s("%s", x[z]);
    }
    free(x);
}

int changeArray(int **a) {

    for (int z = 0; z < 5; ++z) {
        (*a)[z] = 1;
    }
}

我知道有类似的帖子,但我看到的所有帖子似乎都没有解决我的问题,感谢任何帮助!

【问题讨论】:

  • int *x[5] 应为 int x[5]y 相同)和 int changeArray(int **a) 应为 int changeArray(int (*a)[5])
  • 去掉 x 和 y 之前的 *。另外,你不应该调用free(x),因为数组不是堆分配的
  • 使用此语句,您将在指针 x[0], x[1] ... int *x[5] = { 1,5, 中填充地址 1,5,4,3,1 4,3,1};它类似于 int *x = 5;这是无效的,最好采用整数类型数组它不是强制变量为指针类型以通过引用调用。
  • 您是如何没有获得任何编译器诊断信息的?您的帖子中没有提到没有。请找出编译器输出诊断消息的位置!
  • "Access violation writing location 0x00000001." 哎哟!。您正在尝试访问位于 System Reserved 内存池最底部的地址 1 的内存。不好。

标签: c arrays element pass-by-reference


【解决方案1】:

您的程序正在做一些完全出乎意料的事情。

int *x[5] = { 1,5,4,3,1 };
int *y[5]= { 1,5,4,3,1 };

在这里,您正在初始化一堆 int 指针,其值从 1 到 5。因此它们指向无效内存。

然后,这里:

for (int z = 0; z <= 4; ++z) {
    printf_s("%s", x[z]);
}

您是在告诉它在无效内存中打印字符串。

Access violation writing location 0x00000001 中的0x00000001 实际上是int *x[5] = { 1,5,4,3,1 }; 中第一个1 的十六进制表示。

你可能想要的是这个:

int changeArray(int *a) {

    for (int z = 0; z < 5; ++z) {
        a[z] = 1;
    }
}

还有这个:

int main(void) {

    int x[5] = { 1,5,4,3,1 };

    changeArray(x);
    for (int z = 0; z <= 4; ++z) {
        printf("%d", x[z]); // also consider adding space, such as "%d "
    }
}

【讨论】:

  • 干得好,不需要传递指向数组的指针,因为数组具有自动存储类型,其范围在main() 开始...
  • 是的,我认为 OP 误解了指针和数组在 C 中的工作方式。我可以理解,我花了很长时间才正确理解这些内容。
  • 当我们学习时,我们的额头上都有同样的肿块,因为我们的头撞到了同一堵墙上:)
【解决方案2】:

代码应该是这样的:

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

void changeArray(int (*a)[5]);

int main(void) {
    int x[5] = { 1,5,4,3,1 };
    changeArray(&x);
    for (int z = 0; z <= 4; ++z) {
        printf_s("%d", x[z]);
    }
    return 0;
}

void changeArray(int (*a)[5]) {
    for (int z = 0; z < 5; ++z) {
        (*a)[z] = 1;
    }
}

并给出输出:

11111

正如您在 Live Demo 中看到的那样。


以下是我所做的更改:

  • int *x[5] = { 1,5,4,3,1 }; 更改为int x[5] = { 1,5,4,3,1 };
  • 删除y,因为你不使用它。
  • 把你的函数原型改成:void changeArray(int (*a)[5]);,因为你不返回任何东西,参数是 也改变了,传递数组x,就像现在所做的改变一样。
  • 使用%d 打印整数,而不是%s
  • 删除free(x),因为您没有为数组动态分配内存 x,因此您不能手动取消分配。

【讨论】:

  • 感谢 gsamaras 这很有趣 :)
【解决方案3】:
  • int *x[5] 应该是 int x[5]
  • 你根本不需要int y[5]
  • int changeArray(int **a) 应该是 void changeArray(int (*a)[5])
  • 您将指针传递给数组,但什么也不返回。 free(x); 是 错误,x 在堆栈上,不能被释放。
  • printf_s("%s", x[z]); 应该是 printf("%d ", x[z]);x[z]int,所以它需要 %d 作为格式说明符。还要注意它后面的空格,以查看不同的数字,而不仅仅是一个大数字。

这是您更正后的代码https://ideone.com/kwXrFg

【讨论】:

  • 不错的答案 mch,但正如我在回答中提到的那样,x 不需要被释放,它不能被释放。
【解决方案4】:
#include <stdio.h>
#include <stdlib.h>

int changeArray(int *a);

int main(void) {

    int x[5] = { 1,5,4,3,1 };
    int y[5]= { 1,5,4,3,1 };

    changeArray(x);
    for (int z = 0; z <= 4; ++z) {
        printf_s("%s", x[z]);
    }
}

int changeArray(int *a) {

    for (int z = 0; z < 5; ++z) {
        a[z] = 1;
    }
}

【讨论】:

    猜你喜欢
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多