程序很简单,就想打印字符串数组中的每一个字符串
void test(char** s, int size) {
for (int i = 0; i < size; i++)
printf("%d:%s\n", i, s[i]);
}
int main() {
char s[4][10] = { "hello", "whatever", "", "like" };
test(s, 4);
}
编译时报警告如下:
1. char **”与“char [4][10]”的间接级别不同
2. “test”: 形参和实参 1 的类型不同
运行时在test函数的printf出现“引发的异常: 0xC0000005: 读取位置 0x6C6C6568 时发生访问冲突”
以i=0为例进行分析
main函数中,s为一个二维数组,test函数中取s[0],认为这是指向"hello"的指针,用printf访问指向的地址并打印内容
但是由于入参s类型为char**,是一个二级指针,因此test函数中取出的s[0]的内容并非指向"hello"的指针,而是 “hello”本身,于是读取前4个字节"hell"内容作为char*,并用printf去访问相应位置内容。但"hell"所指向地址为非法地址(未申请或者根本就不在堆、栈地址区间),因此发生访问冲突。当然,如果执行的是写操作,也会出现些访问冲突。
访问地址冲突可以通过如下初始化s[4][10]来验证
char s[4][10] = { "\x01\x02\x03\x04", "what", "", "like" }; //让s指向地址的前四个字节内容就为"0x01020304"
运行时的异常就变为“引发的异常: 0xC0000005: 读取位置 0x04030201 时发生访问冲突”(也可以看出我的机器是小端机)
正确的初始化方法
char* s[4] = { "hello", "whatever", "", "like" };
或
char* s1="hello";
char* s2="world";
char* s[2]={s1,s2};
另外还有一篇讲二级指针和二维数组实参形参传递的,送上传送门 http://blog.csdn.net/u014624795/article/details/53201710