【问题标题】:C allocated pointers? What's this?C分配的指针?这是什么?
【发布时间】:2012-01-10 13:26:59
【问题描述】:

我有以下代码。

char a[] = "abcde";
char *b = "fghij";
char *c = malloc(6);
char *d = c;
c = "klmno";

练习说明:

画出数据结构a、b、c和d的图片(带内容), 您可以在其中查看已分配的内容并使用箭头显示如何分配 指针已设置。

我的解决办法是:

      ____________
a -> |a|b|c|d|e|\0|
      ¨¨¨¨¨¨¨¨¨¨¨¨
      ____________
b -> |f|g|h|i|j|\0|
      ¨¨¨¨¨¨¨¨¨¨¨¨
      ____________
c -> |k|l|m|n|o|\0|
      ¨¨¨¨¨¨¨¨¨¨¨¨
      ___________
d -> | | | | | | |
      ¨¨¨¨¨¨¨¨¨¨¨

但是我的解决方案没有被接受,响应是“为指向 b、c、d 但不是 a 的指针分配了内存”。谁能解释一下这是什么意思?

【问题讨论】:

  • 从您的问题中不清楚您的答案是什么以及它有什么问题。请尝试改写它以使其更易于理解。
  • @karlphillip,c 未填写,已重新分配。
  • 不,c 的内容没有复制到d
  • @David 严格来说我们会复制内容。只是指针有一些地址作为内容。
  • 想想看,d指向的数据是随机的,因为它指向的是未初始化的内存。

标签: c pointers memory-management char


【解决方案1】:

这是一个有点神秘的回应,但我想抱怨的是数组a 没有指向该数据;它包含数据。

所以这可能是需要的(没有指针箭头):

    ____________
a  |a|b|c|d|e|\0|
    ¨¨¨¨¨¨¨¨¨¨¨¨

数组名可以作为指针使用,但还是有微妙的不同。

【讨论】:

  • 是的,我就是这么想的。然而,数组本质上不只是指向第一个元素的指针吗?
  • 数组名指向该数组的第一个元素。在这个意义上它是一个指针。
  • 看起来他们想要像this这样的图片。
  • @Pithikos:不,不是。数组a 只是6 个chars 的集合。在某些情况下,a 将评估为指向第一个字符的指针,但这与说 a 一个指针(它不是)不同。
  • @caf "collection of char" 只是一个抽象概念。我同意数组不是指针数据结构。然而,它有一个地址作为内容,就像一个指针一样。这样你就可以说它是一个指针。只是我们这里指的不是数据结构指针。
【解决方案2】:

我会这样画它们:

      ____________
     |a|b|c|d|e|\0|
      ¨¨¨¨¨¨¨¨¨¨¨¨
           a
      ____________
b -> |f|g|h|i|j|\0|
      ¨¨¨¨¨¨¨¨¨¨¨¨
      ____________
c -> |k|l|m|n|o|\0|
      ¨¨¨¨¨¨¨¨¨¨¨¨
      _____________
d -> |g|a|r|b|a|g|e|
      ¨¨¨¨¨¨¨¨¨¨¨¨¨

注意a 如何位于整个数组下方,而不是箭头旁边。这是为了强调a 是一个包含字符串本身的整个数组,而不仅仅是一个指针。这表明你意识到了 arraypointer 之间的区别。

【讨论】:

  • @Andrey:不,不是。数组和指针之间有明显的区别。尽管数组标识符在某些上下文中衰减为指针,但这并不能使它们成为指针。试试sizeof(a)sizeof(b),自己看看有什么不同。
  • 是的,你是对的。但实际上,我认为这并不重要。
  • 你有 d 指向 7 个字节的垃圾;它应该只有 6 个。:)
【解决方案3】:

d指向的内存内容实际上并不确定。它必须包含一些来自malloc() on c 的垃圾

【讨论】:

    【解决方案4】:

    我什至会尝试区分数据指向的生命所在。

      ____________
    a|a|b|c|d|e|\0| (in data segment or on stack)
      ¨¨¨¨¨¨¨¨¨¨¨¨
      _____      ____________
    b|ptr->| -> |f|g|h|i|j|\0| (in rodata)
      ¨¨¨¨¨      ¨¨¨¨¨¨¨¨¨¨¨¨
      _____      ____________
    c|ptr->| -> |k|l|m|n|o|\0| (in rodata)
      ¨¨¨¨¨      ¨¨¨¨¨¨¨¨¨¨¨¨
      _____      ___________
    d|ptr->| -> |X|X|X|X|X|X| (on heap)
      ¨¨¨¨¨      ¨¨¨¨¨¨¨¨¨¨¨
    

    【讨论】:

      【解决方案5】:

      我觉得你说的很对:

          char a[] = "abcde";
          printf("a[]: [%s] length:%d\n", a, strlen(a));
      
          char* b = "fghij";
          printf("*b: [%s] length:%d\n", b, strlen(b));
      
          char* c = (char*)malloc(6);
          char* d = c;
      
          c = "klmno";
          printf("*d = c: d is [%s] length:%d\n", d, strlen(d));
          printf("*d = c: c is [%s] length:%d\n", c, strlen(c));
      

      输出:

      a[]: [abcde] length:5
      *b: [fghij] length:5
      *d = c: d is [] length:0
      *d = c: c is [klmno] length:5
      

      注意:即使strlen() 搜索NULL 字符以便能够迭代字符串数组并计数字符,NULL 本身的出现不会添加到最终总和,这就是它报告 5 个字符而不是 6 个字符的原因。

      至于您的答案未被接受,您的老师可能希望您为数组a 做其他形式的表示,您可能有兴趣与您的同事讨论,但我不认为公平地说,您给出了错误的答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-04
        • 2017-05-08
        • 2016-05-15
        • 2010-09-17
        • 1970-01-01
        • 2015-03-20
        相关资源
        最近更新 更多