C语言char***传参执行一次for循环触发段错误如何解决
问题原因梳理
- 运算符优先级错误:
[]运算符优先级高于解引用运算符*,你写的*what[i]实际等价于*(what[i]),是对三级指针what做下标偏移后再解引用。但what本身仅指向main中hello变量的单个地址空间,i≥1时偏移操作直接访问非法内存,这是触发段错误的核心原因。你预期的写法应该是(*what)[i]:先解引用what拿到hello(即char**类型的字符串数组指针),再取下标访问对应元素。 - 数组长度获取错误:
sizeof(*what)拿到的是char**类型指针的字节长度(64位系统下为8、32位系统下为4),和你在main中分配的20个元素的数组长度完全无关。C语言中裸指针无法携带数组长度信息,必须将长度作为额外参数传入函数。 - 无用操作+内存泄漏+分配大小错误:你先对元素执行
malloc分配空间,计算大小时误用sizeof(*what)(即char**类型的字节长度),和存储字符串需要的char类型大小完全不匹配;随后直接将元素赋值为字符串常量"hello"的地址,malloc申请的空间没有被使用也没有被释放,直接造成内存泄漏。如果后续尝试修改该元素指向的内容,还会因为字符串常量存储在只读段触发段错误。
修正后可运行代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 新增参数接收数组长度 void print_stuff(char*** what, int arr_len) { for(int i = 0; i < arr_len; ++i) { // 若不需要修改字符串内容,可直接赋值字符串常量 // (*what)[i] = "hello"; // 若需要可修改的字符串,使用如下写法 (*what)[i] = malloc(6 * sizeof(char)); // 存储"hello"需要包含末尾\0共6字节 strcpy((*what)[i], "hello"); printf("%s\n", (*what)[i]); } } int main(void) { int arr_len = 20; char** hello; hello = malloc(arr_len * sizeof(*hello)); print_stuff(&hello, arr_len); // 释放内存避免泄漏 for(int i = 0; i < arr_len; ++i) { free(hello[i]); } free(hello); return 0; }
内容的提问来源于stack exchange,提问作者user6833628
相关产品推荐
相关产品推荐

