我正在尝试学习C,更具体地说是指针和malloc((。我编写了以下程序,需要对我收到的警告消息和输出进行一些澄清。
#include<stdio.h>
#include<stdlib.h>
void printem(char *ptr, char loopagain)
{
int i;
for (i = 0; i < loopagain; i++)
{
printf("Found %c at address %c n",ptr[i],&ptr[i]);
}
return;
}
void initializeblock(char *ptr, char loopagain)
{
int i;
for (i = 0; i < loopagain; i++)
{
ptr[i] = 65+i;
}
return;
}
int main()
{
char neededbytes = 10;
char *p;
p = (char *) malloc(neededbytes * sizeof(char));
if(p==NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
else
{
printem(p,neededbytes);
initializeblock(p,neededbytes);
printem(p,neededbytes);
}
free(p);
}
我遇到的第一个问题是我没有得到 10 个 char 元素中的每一个的地址以正确打印为数字。我得到的不是数字,而是符号。这是打印出值和地址的代码行。
printf("Found %c at address %c n",ptr[i],&ptr[i]);
我做错了什么?
第二个问题是在 else 语句中,我有以下代码
printem(p,neededbytes);
initializeblock(p,neededbytes);
printem(p,neededbytes);
最初我使用了 & 之前 p,但收到以下警告
[警告] 从不兼容的指针类型
传递"printem"的参数 1 [注意] 预期的"字符 *",但参数的类型为"字符 **">
我在网上找到的例子表明,一个期望指针的函数应该将地址传递给它,为什么我在使用
printem(&p,neededbytes);
initializeblock(&p,neededbytes);
printem(&p,neededbytes);
另外,当我使用 malloc()
分配块时,除了使用数组括号之外,还有其他方法可以访问/修改数据吗,p[i]
?
有没有办法知道分配的块的大小,这样我就不必将其作为下一行中的参数传递
printem(p,neededbytes);
首先
printf("Found %c at address %c n",ptr[i],&ptr[i]);
应该至少
printf("Found %c at address %p n",ptr[i],(void *)&ptr[i]);
因为,&ptr[i]
是一个地址,它需要%p
格式说明符。然后,printf()
是一个可变参数函数,则只进行默认参数提升,因此您需要将参数转换为void *
,即预期的%p
类型。对转换说明符使用不适当的类型参数会导致未定义的行为。
也就是说,即使这样也救不了你。在你调用printem()
的时候,p
指向的内存位置是未初始化的[#],它的内容是不确定的。使用未初始化的值将再次引导您进入 UB。因此,您需要在尝试打印值之前初始化内存。
然后,检查initializeblock()
的签名
void initializeblock(char *ptr, char loopagain)
以及您收到警告的呼叫
initializeblock(&p,neededbytes);
在此调用中,您尝试传递类型 char **
的&p
,并尝试在 char *
中接收相同的内容,这会触发警告。你应该没问题,像这样的电话
initializeblock(p,neededbytes);
在这种情况下。
最后
有没有办法知道分配的块的大小,这样我就不必在下一行中将其作为参数传递......
恐怕没有。没有仅从指针知道分配大小的标准方法,因此您必须将大小作为第二个参数传递。
[#] malloc()
返回未初始化的内存。