1
struct busData{
int busNum;
char str[SIZE+1]; //SIZE  = 1000
};

int main(){
    struct busData *bus = (struct busData*)calloc(5, sizeof(struct busData));


printf("\n%d", sizeof(bus)); //result is 4
free(bus);    
return 0;
    }

Now It is showing '4' or '8'depending on platform as a result. I think it should display 5040 right? Because I gave 5 value with calloc(). So how can I get 5040? i am using the 3 elements until 'bus+2' and then I am freeing up with free(bus); And i want to know how many elements left (it should show 2008). so i need 5040?

Mukhammad Ali
  • 810
  • 7
  • 14

5 Answers5

2
sizeof(bus)

Here bus is a pointer so sizeof() will return 4 which is the size of the pointer in the platform you used.(depending on the platform used).
If you want to know the size of struct use sizeof(struct busData) or sizeof(*bus)

LearningC
  • 3,182
  • 1
  • 12
  • 19
1

Now It is showing '4' as a result. I think it should display 5040 right?

No, you're wrong. Check the data types.

First of all, a little about sizeof operator, from C11, chapter §6.5.3.4

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. [...]

bus is a pointer, so, sizeof(bus) is the same as sizeof (struct busData*), which is the size of a pointer, which depending on your environment, can give you the result, of which, the common nones are 4 or 8.

After that, there can be padding in between structure elements and at the end, so a structure defined like

struct busData{
int busNum;
char str[SIZE+1]; //SIZE  = 1000
};

defining a variable of that type and trying to check the size via sizeof may not give you (4+1000+1) == 1005 bytes, for most of the environments.

Quoting again,

[....] When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.

So, you need to account for padding also.

That said,

   printf("\n%d", sizeof(bus));

actually causes undefined behavior. You need to write

 printf("\n%zu", sizeof(bus));

as sizeof yields a result of type size_t.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 1
    so can you tell me the way how to get 5040? – Mukhammad Ali Jun 02 '17 at 12:13
  • @MukhammadAli With a pointer to the starting of the memory block, you cannot. If it would have been an array, `sizeof` would have worked. – Sourav Ghosh Jun 02 '17 at 12:15
  • @MukhammadAli you cannot. As you allocate storage for multiple elements of a structure, the compiler will never be able to tell you this amount of memory derived from the size of any data type. This only works for single data objects. – Gerhardh Jun 02 '17 at 12:38
1

You are trying to output the size of the pointer bus instead of the 5 objects pointed to by the pointer.

Try the following demonstrative program

#include <stdio.h>
#include <stdlib.h>

#define SIZE    1000

struct busData
{
    int busNum;
    char str[SIZE+1]; //SIZE  = 1000
};

int main(void) 
{
    struct busData *bus = (struct busData*)calloc(5, sizeof(struct busData));
    printf("\n%zu\n", 5 * sizeof( *bus ) );

    return 0;
}

The program output is

5040

Pay attention to the conversion specifier and the expression used as an argument of the printf call

    printf("\n%zu\n", 5 * sizeof( *bus ) );
               ^^     ^^^^^^^^^^^^^^^^^

Take into account that pointers do not provide information whether they point to a single object or first object of an array of objects. So using the pointer bus you have to specify explicitly how many objects are pointed to by the pointer.

The same result you could get executing the following statement

printf("\n%zu\n", sizeof( struct busData[5] ) );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

How can i identify the size of structure member?

With a pointer to dynamic allocated memory, there is no way to know the size of memory that the pointer points to.

If you need to know the size after the malloc/calloc, you'll simply have to "remember" how much you malloc/calloced, i.e. save it in a variable.

You could wrap it inside another struct and provide a create function. Something like:

struct busData{
    int busNum;
    char str[SIZE+1]; //SIZE  = 1000
};

struct busDataContainer{
    size_t size;
    struct busData* busData;
};

struct busDataContainer createBusData(size_t n)
{
    struct busDataContainer c;
    c.size = n * sizeof(struct busData);
    c.busData = calloc(n, sizeof(struct busData));
    return c;
}

int main(){
    struct busDataContainer bus = createBusData(5);
    printf("\n%zu", bus.size;
    return 0;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
0

I think the code is screwed up from the beginning. The problem with sizeof was already explained in other answers.

Another big problem is this:

Because I gave 5 value with calloc(). So how can I get 5040? i am using the 3 elements until 'bus+2' and then I am freeing up with free(bus); And i want to know how many elements left (it should show 2008). so i need 5040?

This sounds like you want to use the remaining 2 elemens after calling free.

First:

you have 1 pointer. The compiler can tell you the size of the pointer and the size of the single element that the pointer is pointing to. The compiler has no idea that you allocated memory for more than 1 element of that type and hence cannot tell you anything different than size of pointer or size of 1 element.

Second:

There is no concept like "using" some memory. For the compiler and the OS it doesn't matter if you write something to the memory location or not. It doesn't care if some bytes are still (or again) filled with 0.

Third:

If you allocate a block of memory and free it again, the whole block is free'd and mustn't be used any longer. If you expect to have 2008 bytes that you still can use, you are wrong! Your pointer will point to an invalid address after free is called. Using that pointer to access the memory afterwards is undefined behaviour

Gerhardh
  • 11,688
  • 4
  • 17
  • 39