2

Is this possible?

size_t calculate(char *s)
{
    // I would like to return 64
}

int main()
{
    char s[64];

    printf("%d", calculate(s));

    return 0;
}

I want to write a function which calculates the size of the char array declared in main().

1
  • You could use "de" sizeof function. Commented May 4, 2011 at 14:07

6 Answers 6

6

Your function calculate(), given just the pointer argument s, cannot calculate how big the array is. The size of the array is not encoded in the pointer, or accessible from the pointer. If it is designed to take a null-terminated string as an argument, it can determine how long that string is; that's what strlen() does, of course. But if it wants to know how much information it can safely copy into the array, it has to be told how big the array is, or make an assumption that there is enough space.

As others have pointed out, the sizeof() operator can be used in the function where the array definition is visible to get the size of the array. But in a function that cannot see the definition of the array you cannot usefully apply the sizeof() operator. If the array was a global variable whose definition (not declaration) was in scope (visible) where calculate() was written - and not, therefore, the parameter to the function - then calculate() could indicate the size.

This is why many, many C functions take a pointer and a length. The absence of the information is why C is somewhat prone to people misusing it and producing 'buffer overflow' bugs, where the code tries to fit a gallon of information into a pint pot.

Sign up to request clarification or add additional context in comments.

Comments

5

On statically declared char[] you can use operator sizeof, which will return 64 in this case.

printf("%d", sizeof(s));

On dynamically declared char*, it is not possible to get the size of the allocated memory.

Dynamic arrays are obtained through malloc and friends. All the others are statically declared, and you can use sizeof on them, as long as you use it in the same scope as the array was declared (same function, in your case, for example).

2 Comments

You can apply sizeof() to non-static array definitions and get the size of the array. It will work fine for static arrays (both inside and outside functions), and for global arrays, and for auto arrays, and for VLAs (variable-length arrays). It only works where the definition (rather than the declaration) of the array is visible - and signally fails to produce a useful answer with array (meaning pointer) arguments to functions - as in the question. It can't work for dynamically allocated arrays (created using malloc() or relatives).
OK - you're correct. Will the person asking this question understand your non-standard terminology, though? If you explain what it means, then it helps them understand your answer.
3

Yes, it's possible if s has a specific character in the end of it's array. For example you could have s[63] = 125 and by knowing that every other character from 0 to 62 won't be 125, you can do a for loop until you find 125 and return the size of the array.

Otherwise, it's not possible, as s in the function parameter is just a pointer to your array, so sizeof(s) inside calculate will only return your machines pointer size and not 64 as someone could expected.

Comments

1

Unfortunately, you cannot determine from a pointer value alone how many elements are in the corresponding array. You either need some sort of sentinel value in the array (like the 0 terminator used for strings), or you need to keep track of it separately.

What you can do is get the number of bytes or elements in an array using the sizeof operator:

char arr[64];

size_t size = sizeof arr;                 // # of bytes in arr
size_t count = sizeof arr / sizeof *arr;  // # of elements in arr

However, this only works if arr is an array type; if you tried to do this in your function

 size_t calculate(char *s)
 {
   return sizeof s;
 }

it would return the size in bytes of the pointer value, not of the corresponding array object.

Comments

1

No. char *x or char x[] just creates a pointer to a memory location. A pointer doesn't hold any information about the size of the memory region.

However, char *x = "Hello" occupies 6 bytes (including the terminating null), and strlen(x) would return 5. This relies on the null char at the end of the string, strlen still knows nothing about the underlying buffer. So strlen("Hello\000There") would still be 5.

Comments

-1

This is usually done with a macro in C, like:

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))

Whether it's a good idea is a totally different question.

4 Comments

This only works as long as x is statically declared. For dynamically declared arrays one needs to save the length in a separate variable.
@Rick-Rainer: what's a statically declared array? It will work fine for static arrays, and for global arrays, and for auto arrays, and for VLAs (variable-length arrays). It only works where the definition of the array is visible - and signally fails to produce a useful answer with array (meaning pointer) arguments to functions - as in the question. It can't work for dynamically allocated arrays (created using malloc() or relatives). And (sorry Nikolai), the macro is not the solution to the problem raised in the question.
People are just to uptight in the morning :)
Down voting is unfair. :) The idea is good for x as "char x[<something>];". @Jonathan Leffler: See above. There is a good explanation: "char x[64];" <--> "char *x;"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.