c - 为什么在 char** 转换后会出现段错误?

标签 c string casting fault

我正在尝试做这样的事情:

int main()
{
    char strMat[][32] = { {"FIRST"}, {"SECOND"}, };
    printf ("%s\n", strMat[0]);
    test ((char **) strMat);
    return 0;
}

void test (char **strMat)
{
    printf ("%s\n", strMat[0]);
}

我一直无法弄清楚为什么在调用 test() 之前第一个字符串写得正确,但后来我得到了一个段错误。在代码的其他部分,我用 argv 调用 test() 并且它工作正常。为什么尝试在测试函数上打印 strMat[0] 会导致段错误?

最佳答案

char[2][32] 不是char**,而是一个连续的 2*32 字节内存块。这可以通过打印指针来突出显示:

printf("%p %p %p\n", strMat[0], &strMat[0], &strMat[1]);

当您将类型强制转换为 char** 时,您将数组中包含的数据解释为不可避免地指向无效内存的内存地址。

事实上,如果您尝试打印您认为正确的无效地址,例如:

printf("%p\n", ((char**)strMat)[0]);

你得到 0x5453524946,它被解释为字节数组,如 0x54 0x53 0x52 0x49 0x46,产生 'T' 'S' 'R' ' I''F' 显示了问题(字符被颠倒了,因为我假设是一个小端平台)。

关于c - 为什么在 char** 转换后会出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53505521/

相关文章:

C# 通过对象拆箱

java - 在非单例 bean 上的 Spring 代理上修复 BeanNotOfRequiredTypeException?

c - 两条语句中的 strncmp 比一条语句中花费更多时间

c - 字符串数组实现返回段错误

c++ - C/C++ 中的参数传递技术

string - 为什么这个最长公共(public)子序列的 DP 解决方案可以正常工作?

c# - 无法在泛型类型之间进行转换

c - Windows 等同于 Linux 的预读系统调用?

ruby-on-rails - 如何转换字符串以便在 URL 中正确传递它?

c - 使用 strpbrk 分隔字符串,分隔符为 ">>"?