Getting the Size of a C++ Function

How to get the length of a function in bytes?

There is no way in standard C to get the amount of memory occupied by a function.

Find size of a function in C

The space for code is statically allocated by the linker when you build the code. In the case where your code is loaded by an operating system, the OS loader requests that memory from the OS and the code is loaded into it. Similarly static data as its name suggests is allocated at this time, as is an initial stack (though further stacks may be created if additional threads are created).

With respect to determining the size of a function, this information is known to the linker, and in most tool-chains the linker can create a map file that includes the size and location of all static memory objects (i.e. those not instantiated at run-time on the stack or heap).

There is no guaranteed way of determining the size of a function at run-time (and little reason to do so) however if you assume that the linker located functions that are adjacent in the source code sequentially in memory, then the following may give an indication of the size of a function:

int first_function()
{
...
}

void second_function( int arg )
{
...
}

int main( void )
{
int first_function_length = (int)second_function - (int)first_function ;
int second_function_length = (int)main - (int)second_function ;

}

However YMMV; I tried this in VC++ and it only gave valid results in a "Release" build; the results for a "Debug" build made no real sense. I suggest that the exercise is for interest only and has no practical use.

Another way of observing the size of your code of course is to look at the disassembly of the code in your debugger for example.

How do I determine the size of my array in C?

Executive summary:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

Full answer:

To determine the size of your array in bytes, you can use the sizeof
operator:

int a[17];
size_t n = sizeof(a);

On my computer, ints are 4 bytes long, so n is 68.

To determine the number of elements in the array, we can divide
the total size of the array by the size of the array element.
You could do this with the type, like this:

int a[17];
size_t n = sizeof(a) / sizeof(int);

and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.

So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

Another advantage is that you can now easily parameterize
the array name in a macro and get:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);

c programming, How can i get the sizeof a variable through a function using a pointer as a parameter?

In the line

printf("The the size of the string %zu", sizeof(input));

the sizeof operator will give you the size of the pointer input. It will not give you the size of the object that it is pointing to (which may be the size of the array or the length of the string).

In the function main, the definition

unsigned char text[] = "thisisalongkindofstring";

will make text an array of 24 characters: These 24 characters consist of the 23 actual characters and an extra character for the null terminating character. In C, a string is, by definition, a sequence of characters that is terminated by a null character, i.e. a character with the character code 0.

Therefore, in order to determine the length of the string, you must count every character of the string, until you encounter the terminating null character. You can either do this yourself, or you can use the function strlen which is provided by the C standard library.

Also, it is normal to use the data type char for individual characters of a string, not unsigned char. All string handling functions of the C standard library expect parameters of type char *, not unsigned char *, so, depending on your compiler, mixing these data types could give you warnings or even errors.

Another issue is that this line is wrong:

readEachChar(&text);

The function readEachChar seems to expect the function argument to be a pointer to the first character of the string, not a pointer to an entire array. Therefore, you should write &text[0] instead of &text. You can also simply write text, as this expression will automatically decay to &text[0].

After applying all of the fixes mentioned above, your code should look like this:

#include <stdio.h>
#include <string.h>

void readEachChar( char * input )
{
size_t len = strlen( input );

printf( "The size of the string: %zu\n", len );

for ( size_t i = 0; i < len; i++ )
{
printf( "[%x]", input[i] );
}

printf("\n");
}

int main()
{
char text[] = "thisisalongkindofstring";

readEachChar( text );

return 0;
}

This program has the following output:

The size of the string: 23
[74][68][69][73][69][73][61][6c][6f][6e][67][6b][69][6e][64][6f][66][73][74][72][69][6e][67]

Is there any way to get the size of a c function?

The answer is generally no. You can't. One reason is because functions are not necessarily contiguous in memory. So they don't have a "size". Sometimes, compilers (namely ICC) will make jumps out of the function to a remote part of the binary and jump back in.

See a related question here:

how to find function boundaries in binary code

How to get the size of a C function from inside a C program or with inline assembly?

The information about a function size is stored in the ELF Attributes for the corresponding symbol (name). C example code how to parse this programmatically is at the bottom of the Solaris manpage forgelf_getsym(3ELF) (libelf does exist in Linux, *BSD and MacOS as well, you need to look for the st_size field of the GElf_Sym structure), but you also can use objdump / elfdump (Solaris) / readelf (Linux) for the task:

$ objdump -h -d --section=.text foo3.o

foo3.o: file format elf64-x86-64

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000012 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
[ ... ]
Disassembly of section .text:

0000000000000000 <foo>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,0xfffffffffffffffc(%rbp)
7: 89 75 f8 mov %esi,0xfffffffffffffff8(%rbp)
a: 8b 45 f8 mov 0xfffffffffffffff8(%rbp),%eax
d: 03 45 fc add 0xfffffffffffffffc(%rbp),%eax
10: c9 leaveq
11: c3 retq

This is for an unoptimized compile of your code, while the optimized version is:

$ objdump -h -d --section=.text foo3.o

foo3.o: file format elf64-x86-64

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000004 0000000000000000 0000000000000000 00000040 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
[ ... ]
Disassembly of section .text:

0000000000000000 <foo>:
0: 8d 04 37 lea (%rdi,%rsi,1),%eax
3: c3 retq

Note the "Size" change from 0x12 to 4 ? That's what comes from the .size assembler directive.

The "trick" of trying to use inline assembly to give you function sizes / code locations isn't accounting for compiler-generated glue code (function entry prologues / exit epilogues, inline code generation, ...), nor for the compiler re-ordering inline assembly (gcc is notorious to do so), hence it's not generally a great idea to trust this. In the end, it depends on what exactly you're trying to do ...

Edit: A few more references, external as well as on stackoverflow:

  1. From the gcc mailing list, thread on sizeof(function)
  2. what does sizeof (function name) return?
  3. Find size of a function in C
  4. LibELF by example sourceforge project (this is documentation / a tutorial)

How to find the size of a string inside a function in C?

To get the length of a string you use the strlen function. To get the size of the array you need to pass it as an argument.

When you get the size of a pointer, you get the size of the actual pointer and not what it points to. In your case you seem to be on a 64-bit platform where pointers are 64 bits (8 bytes), then dividing that by sizeof(char) (which is defined to always be 1) you get the value 8.

Knowing the size of a C function in the compiled objectfile

I have found that the output of objdump -t xxx will give definitive function size/length values for program and object files (.o).

For example: (From one of my projects)

objdump -t emma | grep " F .text"

0000000000401674 l F .text 0000000000000376 parse_program_header
00000000004027ce l F .text 0000000000000157 create_segment
00000000004019ea l F .text 000000000000050c parse_section_header
0000000000402660 l F .text 000000000000016e create_section
0000000000401ef6 l F .text 000000000000000a parse_symbol_section
000000000040252c l F .text 0000000000000134 create_symbol
00000000004032e0 g F .text 0000000000000002 __libc_csu_fini
0000000000402240 g F .text 000000000000002e emma_segment_count
00000000004022f1 g F .text 0000000000000055 emma_get_symbol
00000000004021bd g F .text 000000000000002e emma_section_count
0000000000402346 g F .text 00000000000001e6 emma_close
0000000000401f00 g F .text 000000000000002f emma_init
0000000000403270 g F .text 0000000000000065 __libc_csu_init
0000000000400c20 g F .text 0000000000000060 estr
00000000004022c3 g F .text 000000000000002e emma_symbol_count
0000000000400b10 g F .text 0000000000000000 _start
0000000000402925 g F .text 000000000000074f main
0000000000401f2f g F .text 000000000000028e emma_open

I've pruned the list a bit, it was lengthy. You can see that the 5th column (the second wide column with lots of zeros....) gives a length value for every function. main is 0x74f bytes long, emma_close is 0x1e6, parse_symbol_section is a paltry 0x0a bytes... 10 bytes! (wait... is that a stub?)

Additionally, I grep'd for just the 'F'unctions in the .text section, thus limiting the list further. The -t option to objdump shows only the symbol tables, so it omits quite a bit of other information not particularly useful towards function length gathering.

I suppose you could use it like this:

objdump -t MYPROG | grep "MYFUNCTION$" | awk '{print "0x" $(NF-1)}' | xargs -I{} -- python -c 'print {}'

An example:

00000000004019ea l F .text 000000000000050c parse_section_header

$ objdump -t emma | grep "parse_section_header$" | awk '{print "0x" $(NF-1)}' | xargs -I{} -- python -c 'print {}'
1292

Checks out, since 0x50c == 1292.

I used $(NF-1) to grab the column in awk since the second field can vary in content and spaces depending on the identifiers relevant to the symbol involved. Also, note the trailing $ in the grep, causing main to find the main function, not the entry with main.c as its name.

The xargs -I{} -- python -c 'print {}' bit is to convert the value from hex to decimal. If anyone can think of an easier way, please chime in. (You can see where awk is sneaking the 0x prefix in there).

Ah, I just remembered that I have an alias for objdump which presets the demangle option for objdump. It'll make things easier to match if you add --demangle to the objdump invocation. (I also use --wide, much easier to read, but doesn't affect this particular output).

This works on any ELF object, library, program, object file, as long as it's NOT stripped. (I tested with and without debugging symbols too)

Hope this helps.

(I looked, parse_symbol_section IS a stub.)

Getting The Size of a C++ Function

No, this will not work:

  1. There is no guarantee that your function only contains a single ret instruction.
  2. Even if it only does contain a single ret, you can't just look at the individual bytes - because the corresponding value could appear as simply a value, rather than an instruction.

The first problem can possibly be worked around if you restrict your coding style to, say, only have a single point of return in your function, but the other basically requires a disassembler so you can tell the individual instructions apart.

C - How does sizeof() of a function call works?

Here, sizeof evaluates the return type of printf. (Here an int)



Related Topics



Leave a reply



Submit