将 char[][] 转换为 char** 会导致段错误? [英] casting char[][] to char** causes segfault?

查看:34
本文介绍了将 char[][] 转换为 char** 会导致段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我的 C 有点生疏,但我想我会用 C 来做我的下一个(小)项目,这样我就可以对它进行改进,不到 20 行我已经有段错误了.

这是我的完整代码:

#define ROWS 4#define COLS 4char main_map[ROWS][COLS+1]={"a.bb","交流","adc.",".dc."};无效的打印地图(字符**地图){国际我;for(i=0;i

我完全不知道这是如何导致段错误的.从 [][] 转换到 ** 时发生了什么!?这是我得到的唯一警告.

<前>rushhour.c:23:3: 警告:从不兼容的指针类型传递print_map"的参数 1rushhour.c:13:7: 注意:应为char **",但参数类型为char (*)[5]"

[][]** 真的不兼容指针类型吗?它们对我来说似乎只是语法.

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆