1

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

readEachChar(unsigned char * input){
      printf("The the size of the string %zu", sizeof(input));

      for (size_t i = 0; i < sizeof(input); i++) // currently it show me the size of the pointer (8 bytes)
      {
        printf("[%x]",input[i]);
      }
      printf("\n");
      
   }


unsigned char text[] = "thisisalongkindofstring";

int main(){
readEachChar(&text);
return 0;
}
  • 1
    `readEachChar(text)` remove the `&` – OrenIshShalom Jan 17 '22 at 14:39
  • 4
    you cannot in this case, you need to pass size as separate argument to function – Iłya Bursov Jan 17 '22 at 14:41
  • 2
    The compiler can't know where and to what kind of data a pointer might be pointing, so the `sizeof` of a pointer will always be the size of the pointer itself. Use `strlen` to get the length of a null-terminated string. Or use the fact that null-terminated strings are just null-terminated. – Some programmer dude Jan 17 '22 at 14:41
  • 2
    **I am voting to reopen the question because** this question deals with a null-terminated character array, whereas the alleged duplicate question deals with an integer array with no sentinel value. Therefore, the two questions are substantially different, and the answers to both questions are also substantially different. – Andreas Wenzel Jan 17 '22 at 16:20

4 Answers4

1

You can't just ask for sizeof(pointer) since you'll get the size of the pointer itself. Instead of that- you can change the function to get the size as parameter:

readEachChar(unsigned char * input, unsigned size)

and send the size from main:readEachChar(&text, sizeof(text));

Another solution is to run over the char until you reach the null - '\0' at the end and count the characters within it- that's what the strlen function does.

Chana
  • 11
  • 5
0

For starters the argument expression in this call

readEachChar(&text);

has the type unsigned char ( * )[24]. But the function parameter has the type unsigned char * that are not compatible types.

So the compiler should issue a message.

If you will write

readEachChar(text);

then within the function you should just call the function strlen like

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

Otherwise if the passed array does not contain a string you have to declare the function with a second parameter that will be assigned with the number of elements in the passed array.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

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]
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • 1
    Re “All string handling functions of the C standard library expect `char`, not `unsigned char`”: Sort of. None of the functions in `` have `char` parameters. Many have `char *` or `const char *` parameters. But they expect them to contain `unsigned char` objects per C 2018 7.24.1 3: “For all functions in this subclause, each character shall be interpreted as if it had the type unsigned `char`”. The `` and `` functions and macros all provide and expect `unsigned char` values. The library is schizophrenic in this regard. – Eric Postpischil Jan 17 '22 at 15:12
  • @EricPostpischil: Yes, that is quite inconsistant. I have changed the sentence to clarify it a bit. – Andreas Wenzel Jan 17 '22 at 15:20
  • Re "seems to expect the function argument to be a pointer to the first character of the string, not a pointer to an entire array" shouldn't the pointer automatically point to first byte? so &text or text is always going to be &text[0]? i added a ```printf("address %x",input); //in the readEachChar function`` it seems to be pointing to the first byte in every case ```readEachChar(&text); //output: address e0897530``` ```readEachChar(text); //output: address e0897530``` ```readEachChar(&text[0]); //output: address e0897530``` –  Jan 17 '22 at 16:48
  • 1
    @dinolin: You are right that the actual value of `&text` and `text` will be the same. However, the types are different. The expression `&text` will evaluate to a pointer to the array as a whole, whereas `text` will evaluate to `&text[0]`, i.e. to a pointer to a single element. You may want to read [this answer](https://stackoverflow.com/a/69481540/12149471) of mine to a different question on why this distinction is important. In any case, as far as the compiler is concerned, these are two different types, and the compiler may therefore produce an error or a warning message if you mix them. – Andreas Wenzel Jan 17 '22 at 17:00
0

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

printf("The the size of the string %zu", sizeof(input)); does print the size of the variable input, which is a pointer. Apparent OP wants the size of something else such as the size of text[].


To get the size of an object, pass that size into to function.

void foo_sz(size_t sz) {
  printf("Size: %zu\n", sz);
}

// Call
foo_sz(sizeof text);

To get the size of an object and the address of the object, pass both.

void foo_both(size_t sz, void *ptr) {
  printf("Size: %zu\n", sz);
  printf("Ptr: %p\n", ptr);
}

// Call
foo_both(sizeof text, text);

To get the sizeof a variable through a function using a pointer as a parameter, prototype per the type

//  123456789012345678901234
// "thisisalongkindofstring"

void foo_1(unsigned char (*ptr)[24]) {
  printf("Size: %zu\n", sizeof *ptr);
  printf("Ptr: %p\n", (void *) ptr);
}

// Call
foo_1(&text);

Of course now code loses a generic aspect, but does meet the goal of "sizeof a variable through a function using a pointer".


Alternatively consider using a macro to call with 1 argument yet pass both size and address.

#define FOO_M(obj)  foo_both(sizeof(obj), &(obj))

// Call
FOO_M(text);

Additional concerns exists if obj is a VLA or an expression.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256