我正在尝试学习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个字符元素中的每个元素的地址作为数字正确打印出来。而不是数字我得到符号。这是打印出值和地址的代码行。
printf("Found %c at address %c \n",ptr[i],&ptr[i]);
我做错了什么?
第二个问题是在else语句中我有以下代码
printem(p,neededbytes);
initializeblock(p,neededbytes);
printem(p,neededbytes);
最初我使用的是&amp;在p之前,但得到了以下警告
[警告]从不兼容的指针类型中传递'printem'的参数1 [注意]预期'char *'但参数类型为'char **'
我在网上找到的例子表明,一个期望指针的函数应该传递给它的地址,为什么我在使用时会得到警告
printem(&p,neededbytes);
initializeblock(&p,neededbytes);
printem(&p,neededbytes);
另外,当我使用malloc()
分配一个块时,除了使用数组括号p[i]
之外,还有另一种访问/修改数据的方法吗?
有没有办法知道分配的块的大小,所以我不必在下一行中将其作为参数传递
printem(p,neededbytes);
答案 0 :(得分:3)
首先
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()
为variadic function,仅进行默认参数提升,因此您需要将参数转换为void *
,即期望的%p
类型。对转换说明符使用不合适的类型参数会导致undefined behavior。
那就是说,即使这样也不会拯救你。在您调用printem()
时,p
指向的内存位置未初始化 [#] ,其内容不确定。使用未初始化的值将再次引导您进入UB。因此,您需要在尝试打印值之前初始化内存。
然后,检查initializeblock()
void initializeblock(char *ptr, char loopagain)
以及您收到警告的电话
initializeblock(&p,neededbytes);
在此次通话中,您尝试传递类型为&p
的{{1}}并尝试在char **
中接收相同内容,从而触发警告。像
char *
在这种情况下。
最后
有没有办法知道分配的块的大小,所以我不必将它作为参数传递给以下行......
我害怕,不。没有标准方法只是从指针知道分配的大小,因此您必须将大小作为第二个参数传递。