3

I'm writing some extremely repetitive code in C (reading XML), and I found that writing my code like makes it easier to copy and paste code in a constructor*:

something_t* something_new(void)
{
    something_t* obj = malloc(sizeof(*obj));
    /* initialize */
    return obj;
}

What I'm wondering is, it is safe to use sizeof(*obj) like this, when I just defined obj? GCC isn't showing any warnings and the code works fine, but GCC tends to have "helpful" extensions so I don't trust it.

* And yes, I realize that I should have just written a Python program to write my C program, but it's almost done already.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • You can even omit the brackets: `(sizeof *obj)` if you like. – Brett Hale Dec 12 '14 at 01:14
  • 1
    possible duplicate of [Why is it safer to use sizeof(\*pointer) in malloc](http://stackoverflow.com/questions/17258647/why-is-it-safer-to-use-sizeofpointer-in-malloc) – Yu Hao Dec 22 '14 at 04:30
  • 2
    This is even [the recommended way](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/) precisely because you can easily see that you have allocated the right amount – M.M Dec 22 '14 at 04:35
  • People keep answering different questions in the answers, and answering my question in the comments :\ – Brendan Long Dec 22 '14 at 17:32

3 Answers3

1
something_t* obj = malloc(sizeof(*obj));

What I'm wondering is, it is safe to use sizeof(*obj) like this, when I just defined obj?

You have a declaration consisting of:

  • type-specifier something_t
  • declarator * obj
  • =
  • initializer malloc(sizeof(*obj))
  • ;

The C standard says in section Scopes of identifiers:

Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag. Each enumeration constant has scope that begins just after the appearance of its defining enumerator in an enumerator list. Any other identifier has scope that begins just after the completion of its declarator.

Since obj has scope that begins just after the completion of its declarator, it is guaranteed by the standard that the identifier used in the initializer refers to the just defined object.

Armali
  • 18,255
  • 14
  • 57
  • 171
0

While we are giving the sizeof like this.

something_t* obj = malloc(sizeof(obj));

It will allocate the memory to that pointer variable as four bytes( bytes allocated to a pointer variable.)

something_t* obj = malloc(sizeof(*obj));

It will take the data type which is declared to that pointer.

For example,

char *p;
printf("%d\n",sizeof(p));

It will return the value as four.

printf("%d\n",sizeof(*p));

Now it will return value as one. Which is a byte allocated to the character. So when we are using the *p in sizeof it will take the datatype. I don't know this is the answer you are expecting.

Karthikeyan.R.S
  • 3,991
  • 1
  • 19
  • 31
0

It's safe. For example,

n = sizeof(*(int *)NULL);

In this case, NULL pointer access doesn't occur, because a compiler can caluculate the size of the operand without knowing the value of "*(int *)NULL" in run time.

The C89/90 standard guarantees the 'sizeof' expression is a constant one; it is translated into a constant (e.g. 0x04) and embedded into a binary code in compilation stage.

In C99 standard, the 'sizeof' expression is not always a compile-time constant, because of introducing variable length array. For example,

n = sizeof(int [*(int *)NULL]);

In this case, the value of "*(int *)NULL" needs to be known in run time to caluculate the size of 'int[]'.

yz2cm
  • 1
  • 1
  • We are only talking about the case `sizeof *variable_name` though – M.M Dec 22 '14 at 04:34
  • In the case of `sizeof *obj` or `sizeof *(T *)NULL` , you know, any pointer access doesn't occur in C89/90 standard. In that respect, it doesn't matter whether variable name or immediate value is assiged. – yz2cm Dec 22 '14 at 06:32