将 char[][] 转换为 char** 会导致段错误吗?
好吧,我的 C 有点生疏了,但我想我应该用 C 来做我的下一个(小)项目,这样我就可以对其进行抛光,并且我已经有不到 20 行的段错误了。
这是我的完整代码:
#define ROWS 4
#define COLS 4
char main_map[ROWS][COLS+1]={
"a.bb",
"a.c.",
"adc.",
".dc."};
void print_map(char** map){
int i;
for(i=0;i<ROWS;i++){
puts(map[i]); //segfault here
}
}
int main(){
print_map(main_map); //if I comment out this line it will work.
puts(main_map[3]);
return 0;
}
我完全不知道这是如何导致段错误的。从 [][]
转换为 **
时会发生什么!?这是我收到的唯一警告。
rushhour.c:23:3: warning: passing argument 1 of ‘print_map’ from incompatible pointer type rushhour.c:13:7: note: expected ‘char **’ but argument is of type ‘char (*)[5]’
[][]
和 **
真的不兼容指针类型吗?对我来说它们似乎只是语法。
Ok my C is a bit rusty but I figured I'd make my next(small) project in C so I could polish back up on it and less than 20 lines in I already have a seg fault.
This is my complete code:
#define ROWS 4
#define COLS 4
char main_map[ROWS][COLS+1]={
"a.bb",
"a.c.",
"adc.",
".dc."};
void print_map(char** map){
int i;
for(i=0;i<ROWS;i++){
puts(map[i]); //segfault here
}
}
int main(){
print_map(main_map); //if I comment out this line it will work.
puts(main_map[3]);
return 0;
}
I am completely confused as to how this is causing a segfault. What is happening when casting from [][]
to **
!? That is the only warning I get.
rushhour.c:23:3: warning: passing argument 1 of ‘print_map’ from incompatible pointer type rushhour.c:13:7: note: expected ‘char **’ but argument is of type ‘char (*)[5]’
Are [][]
and **
really not compatible pointer types? They seem like they are just syntax to me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
char[ROWS][COLS+1]
无法转换为char**
。print_map
的输入参数应该是or
不同之处在于
char**
意味着指向可以像这样取消引用的东西:而
char(* )[n]
是指向连续内存区域的点,如下所示如果将
(char(*)[5])
视为(char**)你得到垃圾:
A
char[ROWS][COLS+1]
cannot be cast into achar**
. The input argument ofprint_map
should beor
The difference being that a
char**
means to point to something that can be dereferenced like this:While a
char(*)[n]
is a points to a continuous memory region like thisIf you treat a
(char(*)[5])
as a(char**)
you get garbage:当您执行此声明时:
您创建了一个字符数组的数组。字符数组只是一个字符块,而数组数组只是一个数组块 - 所以总的来说,
main_map
只是一整堆字符。它看起来像这样:当您将
main_map
传递给print_map()
时,它会将main_map
评估为指向数组第一个元素的指针 -所以这个指针指向该内存块的开头。您强制编译器将其转换为char **
类型。当您在函数内计算
map[0]
时(例如,对于循环的第一次迭代),它会获取map< 指向的
char *
值/代码>。不幸的是,正如您从 ASCII 艺术中看到的那样,map
不指向char *
- 它指向一堆普通的char
s。那里根本没有char *
值。此时,您加载其中一些char
值(4、或 8,或其他数字,具体取决于您平台上的char *
有多大)并尝试解释这些作为char *
值。当
puts()
然后尝试遵循该伪造的char *
值时,您会遇到分段错误。When you do this declaration:
You create an array-of-arrays-of-char. An array-of-char is just a block of chars, and an array-of-arrays is just a block of arrays - so overall,
main_map
is just a whole heap of chars. It looks like this:When you pass
main_map
toprint_map()
, it is evaluatingmain_map
as a pointer to the first element of the array - so this pointer is pointing at the start of that block of memory. You force the compiler to convert this to typechar **
.When you evaluate
map[0]
within the function (eg. for the first iteration of the loop), it fetches thechar *
value pointed to bymap
. Unfortunately, as you can see from the ASCII-art,map
doesn't point to achar *
- it points to a bunch of plainchar
s. There's nochar *
values there at all. At this point, you load some of thosechar
values (4, or 8, or some other number depending on how bigchar *
is on your platform) and try to interpret those as achar *
value.When
puts()
then tries to follow that boguschar *
value, you get your segmentation fault.查看我的代码,我意识到列的数量是恒定的,但这实际上并不重要,因为它只是一个字符串。所以我改变了它,所以 main_map 是一个字符串数组(呃,字符指针)。这使得我可以只使用
**
来传递它:Looking at my code I realized that the amount of columns is constant, but it doesn't actually matter cause it's just a string. So I changed it so main_map is an array of strings(er, char pointers). This makes it so I can just use
**
for passing it around also: