[英]Segmentation fault when running C program (putchar() and multidimensional array pointers)
I'm trying to run the following code on C: 我正在尝试在C上运行以下代码:
#include "ex1_1.h"
void path(char **adj_mat, int u, int v)
{
printf("test\n");
char temp = *adj_mat[1];
putchar(temp);
}
int main()
{
int u = 5;
int v = 5;
char mat[5][5]={
{'0', '1', '1', '1', '0'},
{'0', '0', '0', '0', '1'},
{'0', '0', '0', '0', '0'},
{'0', '0', '0', '0', '0'},
{'0', '0', '0', '0', '0'}
};
char** adj_mat = (char**)&mat;
printf("Mtest\n");
path(adj_mat, u, v);
return 1;
}
and I'm getting "Segmentation fault". 我得到“细分错误”。
I don't know why, I'm guessing that it's related to how I'm using putchar() with multidimensional array pointers. 我不知道为什么,我猜这与我如何将putchar()与多维数组指针一起使用有关。
Thanks. 谢谢。
A char[5][5]
is not a char **
. char[5][5]
不是 char **
。
Declare your path
function as one of these (they are equivalent): 声明您的path
功能为以下功能之一(它们是等效的):
void path(char (*adj_mat)[5], int u, int v)
void path(char adj_mat[5][5], int u, int v)
and use it like 并像这样使用
path(mat, u, v);
Update: Now to the reason for the segfault. 更新:现在是段错误的原因。
mat
is a 5-array of 5-arrays of char
, which will "decay" into a pointer to 5-arrays of char
when used as an expression. mat
是char
的5数组的5数组,当用作表达式时,它将“衰减”为char
5数组的指针。 This means that mat
can be used as if it is a pointer to a 5-array. 这意味着可以像使用5数组的指针一样使用mat
。 In general a n-array of type T
will decay into a pointer of type T
(note that T
does not decay!). 在类型的一般正阵列T
将衰变成类型的指针T
(注意T
不会腐烂!)。
So note you use mat
as an expression when you pass it to your function pass()
. 因此请注意,将mat
传递给函数pass()
时,应将其用作表达式。 In C it is not possible to pass an array as-is to a function, but it can only "receive" pointers. 在C语言中,无法将数组原样传递给函数,但只能“接收”指针。
So what's the difference between a pointer to pointer of char
and a pointer to a 5-array of char
? 那么什么是指针的指针之间的差值char
到5阵列和一个指针char
? Their type. 他们的类型。 And their sizes. 及其大小。
Suppose you have a pointer to a pointer to a char
- let's call it p
and we have a pointer to a 5-array q
. 假设您有一个指向char
的指针的指针,我们将其称为p
,并且有一个指向5数组q
的指针。 In short: char **p
and char (*q)[5]
. 简而言之: char **p
和char (*q)[5]
。
When you write p[i]
, this will be equivalent to *(p+i)
. 当您编写p[i]
,这等效于*(p+i)
。 Here you have pointer arithmetic. 这里有指针算法。 p+i
has the value (which is an adress) p
plus i*sizeof(char *)
because p
points to a char *
. p+i
的值(是一个地址) p
加i*sizeof(char *)
因为p
指向char *
。
When you look at q
, q+i
would have the value q
plus i*sizeof(char[5])
. 当您查看q
, q+i
将具有q
加上i*sizeof(char[5])
。
These will almost always be different! 这些几乎总是不同的!
Update (real answer now): It's even worse in your case as you are "forcing" char (*q)[5]
"to be" a char p**
(via your invalid typecast), so in your call 更新 (现在是真实答案):在您的情况下,甚至更糟,因为您是“强制” char (*q)[5]
“成为” char p**
(通过无效的类型转换),因此在您的通话中
char temp = *adj_mat[1];
adj_mat[1]
will look at the 2nd row of your matrix an try to interpret its value as a pointer (but it is a 5-array!), so when you then dereference via *adj_mat[1]
you will land somewhere in nirvana - segfault! adj_mat[1]
将查看矩阵的第二行,尝试将其值解释为指针(但它是一个5数组!),因此当您通过*adj_mat[1]
取消引用时,您将进入必杀技-segfault!
The conversion (char**)&mat
is undefined behavior. 转换(char**)&mat
是未定义的行为。 &mat
is char(*)[5][5]
(In words, pointer to array of 5 arrays of 5 chars), and you can't convert it to pointer to pointer to char. &mat
是char(*)[5][5]
(换句话说,指向5个5个字符的5个数组的指针),您不能将其转换为char的指针。
I would write path
like (assuming C99): 我会写path
一样(假设C99):
void path(char *arr,int u,int v) {
char (*adj_mat)[v]=arr;
...
}
Change the line 换线
char temp = *adj_mat[1];
to 至
char temp = adj_mat[1];
The problem is that in 问题是
*adj_mat[1];
you try to dereference a pointer to an invalid address, namely the ASCII code of '1' (I suppose). 您尝试取消引用无效地址的指针,即ASCII码“ 1”(我想)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.