char*[2][2]转char***后访问段错误的原因咨询
为什么强制转换
char*** b = (char***)a后访问b[0][0]会触发段错误? 先明确两个变量的本质:
char* a[2][2]是2×2的二维数组,每个元素都是char*类型的指针,内存里是连续排列的4个指针:依次是"123"的地址、"456"的地址、"234"的地址、"567"的地址。char*** b是指向char**类型指针的指针,它的索引访问逻辑是*( *(b + i) + j )。
访问逻辑的差异
当你写a[0][0]时:
a[0]是二维数组的第一行,类型是char*[2],会被隐式转换成指向该行第一个元素的指针(char**类型,值等于&a[0][0],也就是a的起始地址)。a[0][0]等价于*(a[0] + 0),也就是取第一行第一个char*元素——也就是"123"的地址,所以能正常打印字符串。
而强制转换后写b[0][0]时:
b被强制转换成char***,b[0]等价于*(b + 0),也就是直接把a起始位置的内容(即"123"的地址值)当成了一个char**类型的指针。- 接着
b[0][0]等价于*(b[0] + 0),也就是试图访问"123"地址值所指向的内存。但"123"的地址是一个指向字符的指针,它的数值对应内存里的'1'(ASCII码0x31),你把这个数值当成地址去访问,显然是非法内存,直接触发段错误。
地址不同的原因
b和a的地址相同,是因为b就是指向a起始地址的指针,只是类型被强制修改了。- 但
b[0]的取值是a起始位置存储的内容("123"的地址),而a[0]是第一行数组转换后的指针(指向a的起始地址),两者数值完全不同。所以在此基础上的b[0][0]和a[0][0],自然指向的地址也完全不一样。
内容的提问来源于stack exchange,提问作者5reep4thy
相关产品推荐
相关产品推荐

