How to get the real and total length of char * (char array)?

前端 未结 15 2292
小蘑菇
小蘑菇 2020-11-29 00:37

For a char [], I can easily get its length by:

char a[] = \"aaaaa\";
int length = sizeof(a)/sizeof(char); // length=6

However,

相关标签:
15条回答
  • 2020-11-29 01:07

    Given just the pointer, you can't. You'll have to keep hold of the length you passed to new[] or, better, use std::vector to both keep track of the length, and release the memory when you've finished with it.

    Note: this answer only addresses C++, not C.

    0 讨论(0)
  • 2020-11-29 01:07

    So the thing with the sizeof operator is that it returns you the amount of storage needed, in bytes, to store the operand.

    The amount of storage needed to store a char is always 1 byte. So the sizeof(char) will always return 1.

    char a[] = "aaaaa";
    
    int len1 = sizeof(a)/sizeof(char); // length = 6
    int len2 = sizeof(a);              // length = 6;
    

    This is the same for both len1 and len2 because this division of 1 does not influence the equation.

    The reason why both len1 and len2 carry the value 6 has to do with the string termination char '\0'. Which is also a char which adds another char to the length. Therefore your length is going to be 6 instead of the 5 you were expecting.

    char *a = new char[10];
    int length = sizeof(a)/sizeof(char);
    

    You already mentioned that the length turns out to be 4 here, which is correct. Again, the sizeof operator returns the storage amount for the operand and in your case it is a pointer a. A pointer requires 4 bytes of storage and therefore the length is 4 in this case. Since you probably compile it to a 32-bit binary. If you'd created a 64-bit binary the outcome would be 8.

    This explanation might be here already be here. Just want to share my two cents.

    0 讨论(0)
  • 2020-11-29 01:07

    Legit question. I personally think people confuse pointers with arrays as a result of character pointers (char*), which serve almost the same purpose as character arrays (char __[X]). This means that pointers and arrays are not the same, so pointers of course don't contain a specific size, only an address if I could say so. But nonetheless you can try something similar to strlen.

    int ssize(const char* s)
    {
        for (int i = 0; ; i++)
            if (s[i] == 0)
                return i;
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-29 01:15

    char *a = new char[10];

    My question is that how can I get the length of a char *

    It is very simply.:) It is enough to add only one statement

    size_t N = 10;
    char *a = new char[N];
    

    Now you can get the size of the allocated array

    std::cout << "The size is " << N << std::endl;
    

    Many mentioned here C standard function std::strlen. But it does not return the actual size of a character array. It returns only the size of stored string literal.

    The difference is the following. if to take your code snippet as an example

    char a[] = "aaaaa";
    int length = sizeof(a)/sizeof(char); // length=6
    

    then std::strlen( a ) will return 5 instead of 6 as in your code.

    So the conclusion is simple: if you need to dynamically allocate a character array consider usage of class std::string. It has methof size and its synonym length that allows to get the size of the array at any time.

    For example

    std::string s( "aaaaa" );
    
    std::cout << s.length() << std::endl;
    

    or

    std::string s;
    s.resize( 10 );
    
    std::cout << s.length() << std::endl;
    
    0 讨论(0)
  • 2020-11-29 01:19

    There are only two ways:

    • If the memory pointer to by your char * represents a C string (that is, it contains characters that have a 0-byte to mark its end), you can use strlen(a).

    • Otherwise, you need to store the length somewhere. Actually, the pointer only points to one char. But we can treat it as if it points to the first element of an array. Since the "length" of that array isn't known you need to store that information somewhere.

    0 讨论(0)
  • 2020-11-29 01:20

    You can implement your own new and delete functions, as well as an additional get-size function:

    #define CEIL_DIV(x,y) (((x)-1)/(y)+1)
    
    void* my_new(int size)
    {
        if (size > 0)
        {
            int* ptr = new int[1+CEIL_DIV(size,sizeof(int))];
            if (ptr)
            {
                ptr[0] = size;
                return ptr+1;
            }
        }
        return 0;
    }
    
    void my_delete(void* mem)
    {
        int* ptr = (int*)mem-1;
        delete ptr;
    }
    
    int my_size(void* mem)
    {
        int* ptr = (int*)mem-1;
        return ptr[0];
    }
    

    Alternatively, you can override the new and delete operators in a similar manner.

    0 讨论(0)
提交回复
热议问题