【问题标题】:malloc() pointer output clarificationmalloc() 指针输出说明
【发布时间】:2015-08-07 21:42:24
【问题描述】:

我正在尝试学习 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);

最初我在 p 之前使用 & 但收到以下警告

[警告] 从不兼容的指针类型传递“printem”的参数 1
[注意] 预期为 'char *' 但参数类型为 'char **'

我在网上找到的示例表明,期望指针的函数应该将地址传递给它,为什么我在使用时会收到警告

printem(&p,neededbytes);
initializeblock(&p,neededbytes);
printem(&p,neededbytes);

另外,当我使用malloc() 分配块时,除了使用数组括号p[i]之外,还有其他方法可以访问/修改数据吗?

有没有办法知道分配的块的大小,所以我不必在下一行将它作为参数传递

printem(p,neededbytes);

【问题讨论】:

  • 你需要 %p 来打印指针地址,而不是 %c。
  • 关于分配内存块的最后一个问题,请阅读this SO QA

标签: c pointers malloc


【解决方案1】:

首先

  printf("Found %c at address %c \n",ptr[i],&ptr[i]);

应该至少

  printf("Found %c at address %p \n",ptr[i],(void *)&ptr[i]);

因为&amp;ptr[i] 是一个地址,它需要%p 格式说明符。然后,printf() 是一个variadic function,只发生默认参数提升,因此您需要将参数转换为void *,即%p 的预期类型。对转换说明符使用不适当的类型参数会导致 undefined behavior

也就是说,即使这样也救不了你。在您调用printem() 时,p 指向的内存位置未初始化[#],其内容不确定。使用未初始化的值将再次引导您进入 UB。因此,您需要在尝试打印值之前初始化内存。

然后,检查initializeblock()的签名

void initializeblock(char *ptr, char loopagain)

以及您收到警告的电话

initializeblock(&p,neededbytes);

在此调用中,您尝试传递&amp;p 类型为char ** 并尝试在char * 中接收相同的内容,这会触发警告。像

这样的电话应该没问题
initializeblock(p,neededbytes);

在这种情况下。

最后

有没有办法知道分配的块的大小,所以我不必在下一行将它作为参数传递...

恐怕,不。没有标准方法可以仅从指针知道分配的大小,因此您必须将大小作为第二个参数传递。


[#]malloc() returns uninitialized memory.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多