allocating memory for pointee

Discussion in 'C Programming' started by Bill Cunningham, Jan 16, 2013.

  1. I have been trying to understand dereferncing better and came across a
    tutorial that showed this.

    int *x;
    pointer allocated /does that allocate memory for an int/
    or do I need to add this?

    x=malloc(sizeof(int));

    I've never worked knowledgably with this. And if I set the pointer to a
    value, I wouldn't need malloc right?

    int *x;
    int y=42;
    x=&y;
    No malloc needed for x or y right? I've never needed it before.

    Bill
    Bill Cunningham, Jan 16, 2013
    #1
    1. Advertising

  2. Bill Cunningham

    Lew Pitcher Guest

    On Wednesday 16 January 2013 16:16, in comp.lang.c, d
    wrote:

    > I have been trying to understand dereferncing better and came across a
    > tutorial that showed this.
    >
    > int *x;
    > pointer allocated /does that allocate memory for an int/
    > or do I need to add this?


    No,
    int *x;
    does not allocate space for the "pointee". It only allocates space for
    the "pointer".

    > x=malloc(sizeof(int));


    Yes, that will now allocate space for the "pointee", and initialize
    the "pointer" to point at the "pointee"

    > I've never worked knowledgably with this. And if I set the pointer to a
    > value, I wouldn't need malloc right?


    Not always.
    You can take the address of an int, and give that value to the "pointer".

    > int *x;
    > int y=42;
    > x=&y;


    So far, so good. You take the address of y, which is an int, and use that as
    the "pointee" to set the pointer x to.

    > No malloc needed for x or y right?


    Correct.

    > I've never needed it before.




    --
    Lew Pitcher
    "In Skills, We Trust"
    Lew Pitcher, Jan 16, 2013
    #2
    1. Advertising

  3. Bill Cunningham

    Lanarcam Guest

    Le 16/01/2013 22:16, Bill Cunningham a écrit :
    > I have been trying to understand dereferncing better and came across a
    > tutorial that showed this.
    >
    > int *x;
    > pointer allocated /does that allocate memory for an int/


    No, it doesn't. (It allocates memory for x which is a pointer but
    not for the int which it points to)

    > or do I need to add this?
    >
    > x=malloc(sizeof(int));


    That's a possibility, but normally, you should check the return of
    malloc.
    >
    > I've never worked knowledgably with this. And if I set the pointer to a
    > value, I wouldn't need malloc right?
    >
    > int *x;
    > int y=42;
    > x=&y;
    > No malloc needed for x or y right? I've never needed it before.


    Right.
    Lanarcam, Jan 16, 2013
    #3
  4. Bill Cunningham

    Shao Miller Guest

    On 1/16/2013 16:16, Bill Cunningham wrote:
    > I have been trying to understand dereferncing better and came across a
    > tutorial that showed this.
    >
    > int *x;
    > pointer allocated /does that allocate memory for an int/
    > or do I need to add this?
    >
    > x=malloc(sizeof(int));
    >


    Or you could add this:

    x = malloc(sizeof *x);

    That is a touch more precise than the former, because it says "Try to
    allocate enough storage for the pointee of 'x'," rather than "try to
    allocate enough storage for an 'int'" (which so happens to be the right
    amount of storage).

    Using this form, if you decide to change 'int *x;' to 'long *x;' some
    day, you don't need to change the line with the 'malloc'.

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
    Shao Miller, Jan 16, 2013
    #4
  5. Shao Miller wrote:

    > Or you could add this:
    >
    > x = malloc(sizeof *x);
    >
    > That is a touch more precise than the former, because it says "Try to
    > allocate enough storage for the pointee of 'x'," rather than "try to
    > allocate enough storage for an 'int'" (which so happens to be the
    > right amount of storage).
    >
    > Using this form, if you decide to change 'int *x;' to 'long *x;' some
    > day, you don't need to change the line with the 'malloc'.


    Oh I see yes. That makes sense. Is that proper style here?

    Bill
    Bill Cunningham, Jan 17, 2013
    #5
  6. Bill Cunningham

    Shao Miller Guest

    On 1/16/2013 19:10, Bill Cunningham wrote:
    > Shao Miller wrote:
    >
    >> Or you could add this:
    >>
    >> x = malloc(sizeof *x);
    >>
    >> That is a touch more precise than the former, because it says "Try to
    >> allocate enough storage for the pointee of 'x'," rather than "try to
    >> allocate enough storage for an 'int'" (which so happens to be the
    >> right amount of storage).
    >>
    >> Using this form, if you decide to change 'int *x;' to 'long *x;' some
    >> day, you don't need to change the line with the 'malloc'.

    >
    > Oh I see yes. That makes sense. Is that proper style here?
    >


    It's as proper as the form you had picked. The choice is yours.

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
    Shao Miller, Jan 17, 2013
    #6
  7. Shao Miller wrote:
    > On 1/16/2013 19:10, Bill Cunningham wrote:
    >> Shao Miller wrote:
    >>
    >>> Or you could add this:
    >>>
    >>> x = malloc(sizeof *x);

    <snip>

    Does the * in front of the x indicate that x is a pointer? You do not want
    just x then or the compiler wouldn't know it's a pointer?
    Bill Cunningham, Jan 17, 2013
    #7
  8. Bill Cunningham

    Shao Miller Guest

    On 1/17/2013 06:49, Bill Cunningham wrote:
    > Shao Miller wrote:
    >> On 1/16/2013 19:10, Bill Cunningham wrote:
    >>> Shao Miller wrote:
    >>>
    >>>> Or you could add this:
    >>>>
    >>>> x = malloc(sizeof *x);

    > <snip>
    >
    > Does the * in front of the x indicate that x is a pointer? You do not want
    > just x then or the compiler wouldn't know it's a pointer?
    >
    >


    There are two kinds of '*' operator:

    - The unary indirection operator
    - The binary multiplication operator

    the one that's being used above is the unary indirection operator. For
    any expression 'E' that has a pointer type, the expression '*E' means:
    The pointee of 'E'.

    Your declaration of 'x' was:

    int *x;

    So in a later expression, 'x' has a pointer type. Thus, the expression
    '*x' means: The pointee of 'x'.

    So 'sizeof *x' means: The size of the pointee of 'x'.

    '*x' doesn't tell the compiler that 'x' is a pointer. Your declaration
    of 'x' told the compiler that 'x' is a pointer.

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
    Shao Miller, Jan 17, 2013
    #8
  9. Shao Miller wrote:
    > On 1/17/2013 06:49, Bill Cunningham wrote:
    >> Shao Miller wrote:
    >>> On 1/16/2013 19:10, Bill Cunningham wrote:
    >>>> Shao Miller wrote:
    >>>>
    >>>>> Or you could add this:
    >>>>>
    >>>>> x = malloc(sizeof *x);

    >> <snip>
    >>
    >> Does the * in front of the x indicate that x is a pointer? You do
    >> not want just x then or the compiler wouldn't know it's a pointer?
    >>
    >>

    >
    > There are two kinds of '*' operator:
    >
    > - The unary indirection operator
    > - The binary multiplication operator
    >
    > the one that's being used above is the unary indirection operator. For any
    > expression 'E' that has a pointer type, the expression '*E'
    > means: The pointee of 'E'.
    >
    > Your declaration of 'x' was:
    >
    > int *x;
    >
    > So in a later expression, 'x' has a pointer type. Thus, the
    > expression '*x' means: The pointee of 'x'.
    >
    > So 'sizeof *x' means: The size of the pointee of 'x'.
    >
    > '*x' doesn't tell the compiler that 'x' is a pointer. Your
    > declaration of 'x' told the compiler that 'x' is a pointer.


    So for a function that takes a pointer you don't need to pass that *
    operator right?

    void func(void *);
    would be void func(x); for example. I know you could also use

    void func(&x);
    And bypass the pointer altogether and pass the object pointed to (pointee)
    right?

    Bill
    Bill Cunningham, Jan 17, 2013
    #9
  10. Bill Cunningham

    Shao Miller Guest

    On 1/17/2013 08:21, Bill Cunningham wrote:
    > Shao Miller wrote:
    >> On 1/17/2013 06:49, Bill Cunningham wrote:
    >>> Shao Miller wrote:
    >>>> On 1/16/2013 19:10, Bill Cunningham wrote:
    >>>>> Shao Miller wrote:
    >>>>>
    >>>>>> Or you could add this:
    >>>>>>
    >>>>>> x = malloc(sizeof *x);
    >>> <snip>
    >>>
    >>> Does the * in front of the x indicate that x is a pointer? You do
    >>> not want just x then or the compiler wouldn't know it's a pointer?
    >>>
    >>>

    >>
    >> There are two kinds of '*' operator:
    >>
    >> - The unary indirection operator
    >> - The binary multiplication operator
    >>
    >> the one that's being used above is the unary indirection operator. For any
    >> expression 'E' that has a pointer type, the expression '*E'
    >> means: The pointee of 'E'.
    >>
    >> Your declaration of 'x' was:
    >>
    >> int *x;
    >>
    >> So in a later expression, 'x' has a pointer type. Thus, the
    >> expression '*x' means: The pointee of 'x'.
    >>
    >> So 'sizeof *x' means: The size of the pointee of 'x'.
    >>
    >> '*x' doesn't tell the compiler that 'x' is a pointer. Your
    >> declaration of 'x' told the compiler that 'x' is a pointer.

    >
    > So for a function that takes a pointer you don't need to pass that *
    > operator right?
    >


    You don't pass an operator, ever.

    > void func(void *);
    > would be void func(x); for example. I know you could also use
    >
    > void func(&x);
    > And bypass the pointer altogether and pass the object pointed to (pointee)
    > right?
    >


    That second one is not C, so you're mistaken.

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
    Shao Miller, Jan 17, 2013
    #10
  11. On Thu, 17 Jan 2013 06:49:11 -0500, "Bill Cunningham"
    <> wrote:

    >Shao Miller wrote:
    >> On 1/16/2013 19:10, Bill Cunningham wrote:
    >>> Shao Miller wrote:
    >>>
    >>>> Or you could add this:
    >>>>
    >>>> x = malloc(sizeof *x);

    ><snip>
    >
    >Does the * in front of the x indicate that x is a pointer? You do not want
    >just x then or the compiler wouldn't know it's a pointer?


    There is a difference in meaning between the use of the * in a
    declaration and in a statement.

    In a declaration such as
    int *y;
    the * indicates that y is indeed a pointer.

    In a statement such as you quoted, the * is the unary indirection
    operator. This operator requires that its operand be a pointer but it
    does not mean that the operand is a pointer. If you mistakenly apply
    this operator to a non-pointer operand, it does not magically make the
    operand a pointer. Instead you have a syntax error.

    And of course you also have to distinguish between the unary
    indirection operator and the binary multiplication operator.

    Consider
    int a = 1;
    int b = 2;
    int *p = &a;
    int c = b * *p;
    All three asterisks mean something different.

    --
    Remove del for email
    Barry Schwarz, Jan 17, 2013
    #11
  12. On 1/16/2013 4:10 PM, Bill Cunningham wrote:
    > Shao Miller wrote:
    >
    >> Or you could add this:
    >>
    >> x = malloc(sizeof *x);
    >>
    >> That is a touch more precise than the former, because it says "Try to
    >> allocate enough storage for the pointee of 'x'," rather than "try to
    >> allocate enough storage for an 'int'" (which so happens to be the
    >> right amount of storage).
    >>
    >> Using this form, if you decide to change 'int *x;' to 'long *x;' some
    >> day, you don't need to change the line with the 'malloc'.

    >
    > Oh I see yes. That makes sense. Is that proper style here?


    It is just one possible style. And a good one at that. In general I
    would prefer to make my code as type-independent as possible. I.e. the
    guideline I'd follow is that type names belong in declarations. If
    something is not a declaration, it is best to avoid any explicit
    references to type names as much as possible.

    Under this guideline this is "bad"

    x = (int *) malloc(n * sizeof(int));

    and this is "good"

    x = malloc(n * sizeof *x);

    But in the end it is matter of your personal preference.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Jan 17, 2013
    #12
  13. Shao Miller wrote:
    > On 1/17/2013 08:21, Bill Cunningham wrote:
    >> Shao Miller wrote:
    >>> On 1/17/2013 06:49, Bill Cunningham wrote:
    >>>> Shao Miller wrote:
    >>>>> On 1/16/2013 19:10, Bill Cunningham wrote:
    >>>>>> Shao Miller wrote:
    >>>>>>
    >>>>>>> Or you could add this:
    >>>>>>>
    >>>>>>> x = malloc(sizeof *x);
    >>>> <snip>
    >>>>
    >>>> Does the * in front of the x indicate that x is a pointer? You do
    >>>> not want just x then or the compiler wouldn't know it's a pointer?
    >>>>
    >>>>
    >>>
    >>> There are two kinds of '*' operator:
    >>>
    >>> - The unary indirection operator
    >>> - The binary multiplication operator
    >>>
    >>> the one that's being used above is the unary indirection operator.
    >>> For any expression 'E' that has a pointer type, the expression '*E'
    >>> means: The pointee of 'E'.
    >>>
    >>> Your declaration of 'x' was:
    >>>
    >>> int *x;
    >>>
    >>> So in a later expression, 'x' has a pointer type. Thus, the
    >>> expression '*x' means: The pointee of 'x'.
    >>>
    >>> So 'sizeof *x' means: The size of the pointee of 'x'.
    >>>
    >>> '*x' doesn't tell the compiler that 'x' is a pointer. Your
    >>> declaration of 'x' told the compiler that 'x' is a pointer.

    >>
    >> So for a function that takes a pointer you don't need to pass
    >> that * operator right?
    >>

    >
    > You don't pass an operator, ever.
    >
    >> void func(void *);
    >> would be void func(x); for example. I know you could also use
    >>
    >> void func(&x);
    >> And bypass the pointer altogether and pass the object pointed to
    >> (pointee) right?
    >>

    >
    > That second one is not C, so you're mistaken.


    In the example of scanf which takes a pointer I am thinking you use the
    & operator. What's the difference with the second example I gave?

    Bill
    Bill Cunningham, Jan 17, 2013
    #13
  14. Barry Schwarz wrote:
    > On Thu, 17 Jan 2013 06:49:11 -0500, "Bill Cunningham"
    > <> wrote:
    >
    >> Shao Miller wrote:
    >>> On 1/16/2013 19:10, Bill Cunningham wrote:
    >>>> Shao Miller wrote:
    >>>>
    >>>>> Or you could add this:
    >>>>>
    >>>>> x = malloc(sizeof *x);

    >> <snip>
    >>
    >> Does the * in front of the x indicate that x is a pointer? You do
    >> not want just x then or the compiler wouldn't know it's a pointer?

    >
    > There is a difference in meaning between the use of the * in a
    > declaration and in a statement.
    >
    > In a declaration such as
    > int *y;
    > the * indicates that y is indeed a pointer.
    >
    > In a statement such as you quoted, the * is the unary indirection
    > operator. This operator requires that its operand be a pointer but it
    > does not mean that the operand is a pointer. If you mistakenly apply
    > this operator to a non-pointer operand, it does not magically make the
    > operand a pointer. Instead you have a syntax error.
    >
    > And of course you also have to distinguish between the unary
    > indirection operator and the binary multiplication operator.
    >
    > Consider
    > int a = 1;
    > int b = 2;
    > int *p = &a;
    > int c = b * *p;
    > All three asterisks mean something different.


    What I seem to be confused about is when the unary operator is needed
    and when it isn't.

    FILE *fp;
    fp=fopen()...
    not *fp=fopen()...
    And in the example I Shao gave,

    x=malloc(sizeof *x);
    x=malloc(sizeof x); WRONG

    Bill
    Bill Cunningham, Jan 17, 2013
    #14
  15. Bill Cunningham

    Shao Miller Guest

    On 1/17/2013 17:46, Bill Cunningham wrote:
    > Shao Miller wrote:
    >> On 1/17/2013 08:21, Bill Cunningham wrote:
    >>> Shao Miller wrote:
    >>>> On 1/17/2013 06:49, Bill Cunningham wrote:
    >>>>> Shao Miller wrote:
    >>>>>> On 1/16/2013 19:10, Bill Cunningham wrote:
    >>>>>>> Shao Miller wrote:
    >>>>>>>
    >>>>>>>> Or you could add this:
    >>>>>>>>
    >>>>>>>> x = malloc(sizeof *x);
    >>>>> <snip>
    >>>>>
    >>>>> Does the * in front of the x indicate that x is a pointer? You do
    >>>>> not want just x then or the compiler wouldn't know it's a pointer?
    >>>>>
    >>>>>
    >>>>
    >>>> There are two kinds of '*' operator:
    >>>>
    >>>> - The unary indirection operator
    >>>> - The binary multiplication operator
    >>>>
    >>>> the one that's being used above is the unary indirection operator.
    >>>> For any expression 'E' that has a pointer type, the expression '*E'
    >>>> means: The pointee of 'E'.
    >>>>
    >>>> Your declaration of 'x' was:
    >>>>
    >>>> int *x;
    >>>>
    >>>> So in a later expression, 'x' has a pointer type. Thus, the
    >>>> expression '*x' means: The pointee of 'x'.
    >>>>
    >>>> So 'sizeof *x' means: The size of the pointee of 'x'.
    >>>>
    >>>> '*x' doesn't tell the compiler that 'x' is a pointer. Your
    >>>> declaration of 'x' told the compiler that 'x' is a pointer.
    >>>
    >>> So for a function that takes a pointer you don't need to pass
    >>> that * operator right?
    >>>

    >>
    >> You don't pass an operator, ever.
    >>
    >>> void func(void *);
    >>> would be void func(x); for example. I know you could also use
    >>>
    >>> void func(&x);
    >>> And bypass the pointer altogether and pass the object pointed to
    >>> (pointee) right?
    >>>

    >>
    >> That second one is not C, so you're mistaken.

    >
    > In the example of scanf which takes a pointer I am thinking you use the
    > & operator. What's the difference with the second example I gave?
    >


    'void func(&x);' is a syntax violation. It starts out looking like a
    function declaration, but isn't one.

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
    Shao Miller, Jan 17, 2013
    #15
  16. Bill Cunningham

    Shao Miller Guest

    On 1/17/2013 17:50, Bill Cunningham wrote:
    > Barry Schwarz wrote:
    >> On Thu, 17 Jan 2013 06:49:11 -0500, "Bill Cunningham"
    >> <> wrote:
    >>
    >>> Shao Miller wrote:
    >>>> On 1/16/2013 19:10, Bill Cunningham wrote:
    >>>>> Shao Miller wrote:
    >>>>>
    >>>>>> Or you could add this:
    >>>>>>
    >>>>>> x = malloc(sizeof *x);
    >>> <snip>
    >>>
    >>> Does the * in front of the x indicate that x is a pointer? You do
    >>> not want just x then or the compiler wouldn't know it's a pointer?

    >>
    >> There is a difference in meaning between the use of the * in a
    >> declaration and in a statement.
    >>
    >> In a declaration such as
    >> int *y;
    >> the * indicates that y is indeed a pointer.
    >>
    >> In a statement such as you quoted, the * is the unary indirection
    >> operator. This operator requires that its operand be a pointer but it
    >> does not mean that the operand is a pointer. If you mistakenly apply
    >> this operator to a non-pointer operand, it does not magically make the
    >> operand a pointer. Instead you have a syntax error.
    >>
    >> And of course you also have to distinguish between the unary
    >> indirection operator and the binary multiplication operator.
    >>
    >> Consider
    >> int a = 1;
    >> int b = 2;
    >> int *p = &a;
    >> int c = b * *p;
    >> All three asterisks mean something different.

    >
    > What I seem to be confused about is when the unary operator is needed
    > and when it isn't.
    >
    > FILE *fp;
    > fp=fopen()...
    > not *fp=fopen()...
    > And in the example I Shao gave,
    >
    > x=malloc(sizeof *x);
    > x=malloc(sizeof x); WRONG
    >


    The meaning of '*' depends on the context. It can be part of a pointer
    declarator, or can be one of two possible operators used in an
    expression. The unary indirection operator is needed when you wish to
    designate the pointee of a pointer.

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
    Shao Miller, Jan 17, 2013
    #16
  17. On Thu, 17 Jan 2013 17:50:05 -0500, "Bill Cunningham"
    <> wrote:

    >Barry Schwarz wrote:


    snip

    >> There is a difference in meaning between the use of the * in a
    >> declaration and in a statement.
    >>
    >> In a declaration such as
    >> int *y;
    >> the * indicates that y is indeed a pointer.
    >>
    >> In a statement such as you quoted, the * is the unary indirection
    >> operator. This operator requires that its operand be a pointer but it
    >> does not mean that the operand is a pointer. If you mistakenly apply
    >> this operator to a non-pointer operand, it does not magically make the
    >> operand a pointer. Instead you have a syntax error.
    >>
    >> And of course you also have to distinguish between the unary
    >> indirection operator and the binary multiplication operator.
    >>
    >> Consider
    >> int a = 1;
    >> int b = 2;
    >> int *p = &a;
    >> int c = b * *p;
    >> All three asterisks mean something different.

    >
    > What I seem to be confused about is when the unary operator is needed
    >and when it isn't.
    >
    >FILE *fp;
    >fp=fopen()...
    >not *fp=fopen()...
    >And in the example I Shao gave,
    >
    >x=malloc(sizeof *x);
    >x=malloc(sizeof x); WRONG


    You use the name of the pointer when the pointer is what your code is
    dealing with. You code the * to dereference the pointer when the
    object pointed to is what your code is dealing with.

    When you allocate space, the size of the object that will occupy the
    space is what is important, not the size of the pointer that points to
    that space.

    Consider the case where x is pointer to struct and the structure
    contains a dozen int. On a 32 bit system, the size of the pointer
    will usually be 4. The size of the structure will be 48.

    If you code the syntactically correct but logically incorrect
    x = malloc(sizeof x);
    it will only allocate 4 bytes. You will never be able to fit your
    structure into that small a space. If you code
    x = malloc(sizeof *x);
    you are telling the system to reserve enough space for the object that
    will eventually occupy that space.

    --
    Remove del for email
    Barry Schwarz, Jan 18, 2013
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. hall
    Replies:
    4
    Views:
    442
  2. soni29
    Replies:
    6
    Views:
    407
    Kevin Goodsell
    Sep 5, 2003
  3. Axel
    Replies:
    1
    Views:
    731
    stephan beal
    Oct 27, 2003
  4. Sameer
    Replies:
    2
    Views:
    282
    David White
    Nov 3, 2003
  5. Rakesh Kumar
    Replies:
    5
    Views:
    681
    James Kanze
    Dec 21, 2007
Loading...

Share This Page