将 char[][] 转换为 char** 会导致段错误? [英] casting char[][] to char** causes segfault?
问题描述
好吧,我的 C 有点生疏,但我想我会用 C 来做我的下一个(小)项目,这样我就可以对它进行改进,不到 20 行我已经有段错误了.
这是我的完整代码:
#define ROWS 4#define COLS 4char main_map[ROWS][COLS+1]={"a.bb","交流","adc.",".dc."};无效的打印地图(字符**地图){国际我;for(i=0;i
我完全不知道这是如何导致段错误的.从 [][]
转换到 **
时发生了什么!?这是我得到的唯一警告.
[][]
和 **
真的不兼容指针类型吗?它们对我来说似乎只是语法.
char[ROWS][COLS+1]
不能转换为 char**
.print_map
的输入参数应该是
void print_map(char map[][COLS+1])
或
void print_map(char (*map)[COLS+1])
<小时>
区别在于 char**
意味着指向可以像这样取消引用的内容:
(char**)map|v+--------+--------+------+--------+-- ...|0x1200 |0x1238 |空 |0x1200 |+----|---+----|---+--|---+----|---+--- ...v |= |+-------+ |||"富" |<-----------------'+-------+ |v+--------------+|你好世界" |+--------------+
虽然 char(*)[n]
是指向这样的连续内存区域
(char(*)[5])map|v+-----------+---------+---------+-------------+-- ...|"foo " |你好" |"世界" |"d " |+-----------+---------+---------+-------------+-- ...
如果你把 (char(*)[5])
当作 (char**)
你会得到垃圾:
(char**)map|v+-----------+---------+---------+-------------+-- ...|"foo " |你好" |"世界" |"d " |+-----------+---------+---------+-------------+-- ...强制转换 (char[5]) 到 (char*):+------------+------------+------------+------------+-- ...|0x6f6f66 |0x6c686500 |0x77206f6c |0x646c726f |+----|-----+---------|--+------|-----+------|-----+-- ...v |||+--------------+ ||v|"hsd®yœâñ~22" |||发射导弹+--------------+ ||v v没有你的进程内存段错误
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.
A char[ROWS][COLS+1]
cannot be cast into a char**
. The input argument of print_map
should be
void print_map(char map[][COLS+1])
or
void print_map(char (*map)[COLS+1])
The difference being that a char**
means to point to something that can be dereferenced like this:
(char**)map
|
v
+--------+--------+------+--------+-- ...
| 0x1200 | 0x1238 | NULL | 0x1200 |
+----|---+----|---+--|---+----|---+-- ...
v | = |
+-------+ | |
| "foo" | <-----------------'
+-------+ |
v
+---------------+
| "hello world" |
+---------------+
While a char(*)[n]
is a points to a continuous memory region like this
(char(*)[5])map
|
v
+-----------+---------+---------+-------------+-- ...
| "foo " | "hello" | " worl" | "d " |
+-----------+---------+---------+-------------+-- ...
If you treat a (char(*)[5])
as a (char**)
you get garbage:
(char**)map
|
v
+-----------+---------+---------+-------------+-- ...
| "foo " | "hello" | " worl" | "d " |
+-----------+---------+---------+-------------+-- ...
force cast (char[5]) into (char*):
+----------+------------+------------+------------+-- ...
| 0x6f6f66 | 0x6c686500 | 0x77206f6c | 0x646c726f |
+----|-----+---------|--+------|-----+------|-----+-- ...
v | | |
+---------------+ | | v
| "hsd®yœâñ~22" | | | launch a missile
+---------------+ | |
v v
none of your process memory
SEGFAULT
这篇关于将 char[][] 转换为 char** 会导致段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!