简体   繁体   English

为什么这个 function 会导致段错误?

[英]Why is this function causing a segfault?

I have a 2D array that I'm trying to pass through to a function, but each time I try to access the array from the function I get a segmentation fault我有一个二维数组,我试图将其传递给 function,但每次我尝试从 function 访问数组时都会出现分段错误

#include <stdio.h>
#define N 100

void create_magic_square(int n, int magic_square[N][N]);
void print_magic_square(int n, int magic_square[N][N]);


int main(void) {
    int n;

    printf("This program, creates a magic square of a specified size.\nThe size must be an odd number between 1 and 99.\nEnter size of magic square: ");
    scanf("%d", &n);

    int magic_square[n][n];

    create_magic_square(n, magic_square[N][N]);
    print_magic_square(n, magic_square[N][N]);
    return 0;
}

void create_magic_square(int n, int magic_square[N][N]) {

    int i, row, col, next_row, next_col;
    for (row = 0; row < n; row++) {
        for (col = 0; col < n; col++) {
            magic_square[row][col] = 0;
        }
    }
}

The for loop is supposed to fill the array with zeroes and then move on to a while loop, but once it hits 'magic_square[row][col] = 0;', I get a segfault as seen here: for 循环应该用零填充数组,然后继续执行 while 循环,但是一旦它达到 'magic_square[row][col] = 0;',我会得到一个 segfault,如下所示:

The size must be an odd number between 1 and 99.
Enter size of magic square: 5

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400894 in create_magic_square (n=5, magic_square=0x2e2f706d) at q2.c:26
26                  magic_square[row][col] = 0;

I don't know what to do from here, what might be the cause of the problem?我不知道从这里该怎么做,问题的原因可能是什么?

The type signature of的类型签名

void create_magic_square(int n, int magic_square[N][N]);

is actually:实际上是:

void create_magic_square(int n, int (*magic_square)[N]);

It takes a pointer to the first element of an array whose elements are arrays of N integers.它需要一个指向数组的第一个元素的指针,该数组的元素是 N 个整数的 arrays。

This declaration:本声明:

int magic_square[n][n];

produces a C99 variable-length ARRAY (VLA): an 5-element array of 5-element arrays of int.产生一个 C99 可变长度数组 (VLA):一个由 int 的 5 元素 arrays 组成的 5 元素数组。 This is not compatible with what the function expects.这与 function 所期望的不兼容。 But, never mind that, this is not even passed to the function in any manner that resembles correct:但是,没关系,这甚至没有以任何类似于正确的方式传递给 function:

create_magic_square(n, magic_square[N][N]);

Here, the expression magic_square[N][N] accesses the magic_square out-of-bounds (undefined behavior) to retrieve an int value, which is then passed as a pointer argument.在这里,表达式magic_square[N][N]访问magic_square越界(未定义的行为)以检索一个int值,然后将其作为指针参数传递。 That is a constraint violation;那是违反约束的; the compiler should produce a diagnostic here (likely to be worded as being about an integer to pointer conversion without a cast).编译器应该在这里产生一个诊断(可能被表述为关于 integer 到没有强制转换的指针转换)。

The expression we want looks like:我们想要的表达式如下所示:

create_magic_square(n, magic_square);

but for that to be correct, the function has to receive the VLA in the correct way.但要做到这一点,function 必须以正确的方式接收 VLA。

Here is a diff between your program and a working one:这是您的程序和工作程序之间的差异:

--- magicsquare-ORIG.c  2019-10-10 16:14:50.437827772 -0700
+++ magicsquare.c   2019-10-10 16:17:17.896145951 -0700
@@ -1,8 +1,7 @@
 #include <stdio.h>
-#define N 100

-void create_magic_square(int n, int magic_square[N][N]);
-void print_magic_square(int n, int magic_square[N][N]);
+void create_magic_square(int n, int magic_square[n][n]);
+void print_magic_square(int n, int magic_square[n][n]);


 int main(void) {
@@ -13,17 +12,28 @@

     int magic_square[n][n];

-    create_magic_square(n, magic_square[N][N]);
-    print_magic_square(n, magic_square[N][N]);
+    create_magic_square(n, magic_square);
+    print_magic_square(n, magic_square);
     return 0;
 }

-void create_magic_square(int n, int magic_square[N][N]) {
+void create_magic_square(int n, int magic_square[n][n]) {

-    int i, row, col, next_row, next_col;
+    int row, col;
     for (row = 0; row < n; row++) {
         for (col = 0; col < n; col++) {
             magic_square[row][col] = 0;
         }
     }
 }
+
+void print_magic_square(int n, int magic_square[n][n]) {
+
+    int row, col;
+    for (row = 0; row < n; row++) {
+        for (col = 0; col < n; col++) {
+            printf("%d,", magic_square[row][col]);
+        }
+        putchar('\n');
+    }
+}

We lose the N macro, add a print_magic_square function, call the functions properly, and drop some unused local variables.我们丢失了N宏,添加了print_magic_square function,正确调用函数,并删除了一些未使用的局部变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM