将二维数组分配给全局int**指针

huangapple go评论83阅读模式
英文:

Assigning two dimentional array to global int** pointer

问题

我写了以下代码,但是编译失败并显示以下消息:

>程序接收到信号 SIGSEGV,分段错误。
main ()  qary_code.cpp 的第 130  out<<four_ary_matrix[i][j]<<" ";
(gdb)

我想将二维数组传递给一个函数,但长度 `len` 会变化,所以我也想知道如何将二维数组传递给函数。

代码:

```c++
int** global_fourary_matrix;

void print_ary(int** ary, int len){
    
    for(int i=0;i<len;i++) {
        for(int j=0;j<len;j++) {
            cout<<ary[i][j]<<" ";
        }
        cout<<endl;
    }
}

void main(){

    int four_ary[][4] ={ {0,0,0,0}, {0,1,2,3}, {0,2,3,1}, {0,3,1,2} };
    global_fourary_matrix = (int**) four_ary;

    for(int i=0;i<4;i++) {
        for(int j=0;j<4;j++) {
            cout<<global_fourary_matrix[i][j]<<" ";
        }
        cout<<endl;
    }
    
    int len=4;
    print_ary(global_fourary_matrix, len);
}

另一种写法是

global_fourary_matrix = (int**) &(four_ary[0]);

然而,编译器仍然报同样的错误。


<details>
<summary>英文:</summary>

I wrote the following code, however compilation fails with the message


&gt;Program received signal SIGSEGV, Segmentation fault.
main () at qary_code.cpp:130 out&lt;&lt;four_ary_matrix[i][j]&lt;&lt;&quot; &quot;;
(gdb)

I want to pass the 2D array to a function, but the length `len` will change, so I&#39;m also wondering how to pass the 2D array to the function

code:

```c++
int** global_fourary_matrix;

void print_ary(int** ary, int len){
    
    for(int i=0;i&lt;len;i++) {
        for(int j=0;j&lt;len;j++) {
            cout&lt;&lt;ary[i][j]&lt;&lt;&quot; &quot;;
        }
        cout&lt;&lt;endl;
    }
}

void main(){

    int four_ary[][4] ={ {0,0,0,0}, {0,1,2,3}, {0,2,3,1}, {0,3,1,2} };
    global_fourary_matrix = (int**) four_ary;

    for(int i=0;i&lt;4;i++) {
        for(int j=0;j&lt;4;j++) {
            cout&lt;&lt;global_fourary_matrix[i][j]&lt;&lt;&quot; &quot;;
        }
        cout&lt;&lt;endl;
    }
    
    int len=4;
    print_ary(global_fourary_matrix, len);
}

another written style was

global_fourary_matrix = (int**) &amp;(four_ary[0]);

however, the compiler still say the same thing

答案1

得分: 1

使用int**之外的其他方法更好,但如果您真的需要将2D数组传递给int**类型的参数...您可以像这样做:

void print_ary(int** ary, int len);

int main()
{
	//您想将这个2D数组传递给函数“print_ary”,但不能直接这样做。
	int four_ary[][4] = { {0,0,0,0}, {0,1,2,3}, {0,2,3,1}, {0,3,1,2} };
	
	//所以,在这里,
	//创建`int*[]`类型的数组。
	//每个元素都是`int*`类型,并指向2D数组“four_ary”对应的行。
	int *Rows[] = { four_ary[0], four_ary[1], four_ary[2], four_ary[3] };
	//然后,传递数组“Rows”而不是2D数组“four_ary”。
	print_ary(Rows, 4);
}
英文:

Employing some other way rather than int** is better, but if you really need to pass your 2D array to int** type argument... what you can do is like this:

void print_ary(int** ary, int len);

int main()
{
	//You want pass this 2D array to the function &quot;print_ary&quot;, but you can not do it directly.
	int four_ary[][4] ={ {0,0,0,0}, {0,1,2,3}, {0,2,3,1}, {0,3,1,2} };
	
	//So, here,
	//Creating `int*[]` type array.
	//Each element is `int*` type and pointing correspond row of the 2D array &quot;four_ary&quot;.
	int *Rows[] = { four_ary[0], four_ary[1], four_ary[2], four_ary[3] };
	//And, passing the array &quot;Rows&quot; instead of the 2D array &quot;four_ary&quot;.
	print_ary( Rows, 4 );
}

答案2

得分: 1

您已经被告知,int[][4]不是int**,但我想我可以稍微说明一下它们之间的区别。

int[][4]是一个数组,其中每个元素本身都是一个包含四个int的数组。这导致了一块单一的连续内存块,其中A[0][0]直接跟在A[0][1]后面,A[0][3]直接跟在A[1][0]后面。

另一方面,int**是一个指向指针数组(int*数组)的指针,其中每个数组元素本身指向一个int数组。在这种情况下,每个单独的数组都是一块连续的内存块,但没有关于这些数组在内存中如何相对排列的限制。此外,对于各个子数组的长度没有限制。

那么,如果您尝试像访问int**那样访问int[][4]会发生什么情况呢?如果您在B实际上指向A的情况下执行B[0][0],那么您将获取A[0]处的元素(即A[0][0]处的int),并将其视为指向第一个子数组的指针 - 对其进行解引用并尝试访问它所指向的内容。在您的情况下,第一个int0,因此实际上您正在尝试访问一个NULL指针,从而导致分段错误。

附:这是对情况的一种略微简化的看法,不考虑像int与指针的位宽等因素。可以说:如果这样做,情况不会变得更好。

英文:

You have been told that an int[][4] is not an int**, but I thought I would illustrate the difference a bit.

An int[][4] is an array where each element is itself an array of exactly four ints. This results in a single contiguous chunk of memory where A[0][0] is followed directly by A[0][1], and A[0][3] is followed directly by A[1][0].

将二维数组分配给全局int**指针

On the other hand, an int** is a pointer to an array of pointers (array of int*), where each array element itself points to an array of ints. Here each individual array is a contiguous chunk of memory, but there are no restrictions on how the arrays are arranged in memory relative to each other. Also, there is no restriction on the length of the individual sub-arrays.

So what happens if you try to access an int[][4] as if it was a int**? Well, if you do B[0][0] where B actually points to A, then you are going to take the element at A[0] (= the int at A[0][0]) and treat it as a pointer to the first sub-array - dereferencing it and trying to access whatever it points to. In your case the first int is 0, so essentially you try to access a NULL pointer giving you a segmentation fault.

Ps. This is a somewhat simplified look at the situation, and does not take stuff like the bit-width of int vs. pointer into account. Suffice to say: If you do it does not get better.

huangapple
  • 本文由 发表于 2023年7月11日 14:09:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76659115.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定