我想使用函数为指针分配一些内存。以下是我编写的代码:
#include <stdio.h>
#include <stdlib.h>
int test( unsigned char **q)
{
*q = (unsigned char *) malloc(250);
if(*q == NULL)
{
printf("n Error: failed to allocate memory");
return -1;
}
// *q[0] = 10;
// *q[1] = 10;
*q[2] = 10;
return 0; /* Returns 0 on success, non-zero value on failure */
}
int main(void)
{
unsigned char *p;
// printf("n &p = %u", &p);
int result = test(&p);
// printf("n p[2] = %d", p[2]);
return 0;
}
如果我用*q[0]
或*q[1]
写东西,没有错误。但是当我尝试写一些东西来*q[2]
时,它会给出"分段错误(核心转储)"。
此外,我使用除 p[0]
之外的所有数据都p[ ]
0 获取
这段代码有什么问题?
由于 C 语言的运算符优先级,对于 *q[2]
,[]
运算符在运算符之前*
计算。
所以地址q + 2
的值*q[2]
。你想要的是*q + 2
的价值。所以使用(*q) + 2
.
*q[0]
或*q[1]
没有给出分段错误,因为地址q + 0
,q + 1
已分配给您的进程。
地址q + 2
未分配给您的进程,因此分段错误。
由于缺少显式括号,因此默认运算符优先级生效,您的表达式被错误地解释。
对于像这样的表达式
*q[2]
它被解释为
*(q[2])
这是你在这里不想要的。指针算术支持数据类型,因此,x + 1
或x[1]
将产生不同的结果,当
-
x
是类型char *
-
x
属于char **
型。
你需要写
(*q)[2] = 10;
显式地,首先取消引用q
以获取char *
,然后使用索引来获取字符。
而不是这个错误的分配
*q[2] = 10;
这是由于运算符优先级等同于
*( q[2] ) = 10;
因此,取消引用的指针 q[2] 未初始化并且具有不确定的值。你应该写成
( *q )[2] = 10;
甚至只是喜欢
q[0][2] = 10;
另一种方法是引入一个中间变量并使用它来初始化数组的元素。例如
char *p = *q;
p[2] = 10;
这允许使用指针来逃避这种错误。