8

I have the below code.

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

And the exercise states:

Draw a picture of the data structures a, b, c and d(with content), where you can see what has been allocated and use arrows to show how pointers are set.

My solution is:

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

However my solution did not get accepted and the response was "allocated memory for a pointer to b, c, d but not a". Can someone explain me what this means?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Pithikos
  • 18,827
  • 15
  • 113
  • 136

5 Answers5

9

It's a slightly cryptic response, but I guess the complaint is that the array a doesn't point to that data; it contains the data.

So this might be what is required (without the pointer arrow):

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

The name of an array can be used as a pointer, but it still has a subtly different meaning.

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
  • Yes that's what I thought. However isn't array essentially just a pointer to the first element? – Pithikos Dec 01 '11 at 11:41
  • 2
    The name of an array points to the very first element of that array. It's a pointer in this sense. – karlphillip Dec 01 '11 at 11:41
  • 4
    It looks like they wanted picture like [this](http://c-faq.com/aryptr/aryptr2.html). – Piotr Praszmo Dec 01 '11 at 11:43
  • 1
    @Pithikos: No, it's not. The array `a` is just the collection of 6 `char`s. In some circumstances `a` will evaluate to a pointer to the first character, but that's not the same thing as saying that `a` *is* a pointer (which it is not). – caf Dec 01 '11 at 11:59
  • 1
    @caf "collection of char" is just an abstract notion. I agree that an array is not the pointer data structure. However it has an address as content just as a pointer. In that way you can say it's a pointer. It's just that we don't mean the data structure pointer in this case. – Pithikos Dec 01 '11 at 12:09
  • @Pithikos: A collection of 6 chars is no more abstract than a single char. The content of the array is the 6 chars that make it up; no more, no less. – caf Dec 01 '11 at 12:12
  • The real explanation is here http://stackoverflow.com/questions/1335786/c-differences-between-pointer-and-array a still points to the data. The data is just allocated on the stack and copied. – user606723 Dec 01 '11 at 15:11
  • @Pithikos Why do you ask the question here if you already appear to know all the answers? – David Heffernan Dec 01 '11 at 15:19
7

I would draw them like this:

      ____________
     |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|
      ¨¨¨¨¨¨¨¨¨¨¨¨¨

Notice how the a is below the whole array, not next to an arrow. This is to emphasize that a is a whole array that contains the string itself, not just a pointer. This shows that you realise the difference between an array and a pointer.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
  • 3
    @Andrey: no, it's not. There's a distinct difference between an array and a pointer. Although array identifiers decay to a pointer in certain contexts, that doesn't make them pointers. Try `sizeof(a)` and `sizeof(b)` and see the difference for yourself. – Blagovest Buyukliev Dec 01 '11 at 11:48
  • Yes, you're right at this point. But actually it doesn't really matter in here, I think. – Andrey Atapin Dec 01 '11 at 11:51
  • 1
    You have `d` pointing to 7 bytes of garbage; it should only be 6. :) – Graham Borland Dec 01 '11 at 11:59
1

Content of memory pointing by d is not determined actually. It must be contain some garbage which comes from malloc() on c

Andrey Atapin
  • 7,745
  • 3
  • 28
  • 34
1

I would even try to distinguish where the data pointed to lives.

  ____________
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)
  ¨¨¨¨¨      ¨¨¨¨¨¨¨¨¨¨¨
glglgl
  • 89,107
  • 13
  • 149
  • 217
1

I think you are pretty much right:

    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));

Outputs:

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

Note: Even though strlen() searches for the NULL character to be able to iterate on an array of strings and count characters, the ocurrence of NULL itself is not added to the final sum, that's why it reports 5 characters instead of 6.

As for your answer not being accepted, there is probably some other form of representation your teacher was expecting you to do for array a, you might be interested to talk to your colleagues about it, but I don't think is fair to state that you gave a wrong answer.

karlphillip
  • 92,053
  • 36
  • 243
  • 426