mmu*_*lva 14 c arrays parameters pointers segmentation-fault
我想要一个简单的函数,它接收一个字符串并在一些解析后返回一个字符串数组.所以,这是我的功能签名:
int parse(const char *foo, char **sep_foo, int *sep_foo_qty) {
int i;
char *token;
...
strcpy(sep_foo[i], token); /* sf here */
...
}
Run Code Online (Sandbox Code Playgroud)
然后我称之为:
char sep_foo[MAX_QTY][MAX_STRING_LENGTH];
char foo[MAX_STRING_LENGTH];
int sep_foo_qty, error;
...
error = parse(foo, sep_foo, &sep_foo_qyt);
...
Run Code Online (Sandbox Code Playgroud)
这样我在编译期间会收到警告:
warning: passing argument 2 of 'parse' from incompatible pointer type
Run Code Online (Sandbox Code Playgroud)
然后在标记为/*sf的行中执行期间出现分段错误*/
我的C代码有什么问题?
提前致谢
Rob*_*edy 28
警告是完全正确的.你的函数想要一个指针数组.你给它一个数组数组.
预期:
sep_foo:
+------+ +-----+
|char**|--> 0: |char*|-->"string1"
+------+ +-----+
1: |char*|-->"string2"
+-----+
*sep_foo_qty-1: |... |
+-----+
你提供的是什么:
sep_foo:
+--------------------------------+
0: | char[MAX_STRING_LENGTH] |
+--------------------------------+
1: | char[MAX_STRING_LENGTH] |
+--------------------------------+
MAX_QTY-1: | ... |
+--------------------------------+
具有类型元素的数组X可以"衰减"为指针指向X,或X*.但是X不允许在该转换中改变价值.只允许一次衰减操作.你需要它发生两次.在你的情况下,X是阵列的MAX_STRING_LENGTH.该函数希望X成为指向char的指针.由于它们不相同,编译器会发出警告.我有点惊讶它只是一个警告,因为编译器允许发生的事情没有任何好处.
在您的函数中,您可以编写以下代码:
char* y = NULL;
*sep_foo = y;
Run Code Online (Sandbox Code Playgroud)
这是法律代码,因为sep_foo是char**,所以*sep_foo是char*,所以是y; 你可以分配它们.但随着你试图做什么,*sep_foo不会真的是一个char*; 它会指向一个char数组.实际上,您的代码将尝试执行此操作:
char destination[MAX_STRING_LENGTH];
char* y = NULL;
destination = y;
Run Code Online (Sandbox Code Playgroud)
您不能将指针分配给数组,因此编译器会警告该调用没有问题.
有两种方法可以解决这个问题:
更改在sep_foo调用端声明和分配的方式,使其与函数期望接收的方式匹配:
char** sep_foo = calloc(MAX_QTY, sizeof(char*));
for (int i = 0; i < MAX_QTY; ++i)
sep_foo[i] = malloc(MAX_STRING_LENGTH);
Run Code Online (Sandbox Code Playgroud)
或者,等效地
char* sep_foo[MAX_QTY];
for (int i = 0; i < MAX_QTY; ++i)
sep_foo[i] = malloc(MAX_STRING_LENGTH);
Run Code Online (Sandbox Code Playgroud)更改函数的原型以接受您真正给出的内容:
int parse(const char *foo, char sep_foo[MAX_QTY][MAX_STRING_LENGTH], int *sep_foo_qty);
Run Code Online (Sandbox Code Playgroud)cod*_*gic 15
参数2应该是
char sep_foo[][MAX_STRING_LENGTH]
Run Code Online (Sandbox Code Playgroud)
为了澄清,您传递一个指向parse()的指针并将其视为指向指针的指针.C中的多维数组不是指针数组.它是数组变量指向的单个内存块.你不能两次取消引用它.