简体   繁体   中英

Not sure why I am getting different lengths when using a string or a char

When I call gethostname using a char my length 25 but when I use a string my length is 64. Not really sure why. Both of them I am declaring the same size on HOST_NAME_MAX.

        char hostname[HOST_NAME_MAX];
        BOOL host =  gethostname(hostname, sizeof hostname);
        expectedComputerName = hostname;
        int size2 = expectedComputerName.length();

        std::string test(HOST_NAME_MAX, 0);
        host =  gethostname(&test[0], test.length());
        int  testSize = test.length();

An std::string object can contain NUL s (ie '\\0' characters). You are storing the name in the first bytes of a string object that was created with a size of HOST_NAME_MAX length.

Storing something in the beginning of the string data won't change the length of the string that remains therefore HOST_NAME_MAX .

When creating a string from a char pointer instead the std::string object created will contain up to, but excluding, the first NUL character ( 0x00 ). The reason is that a C string cannot contain NUL s because the first NUL is used to mark the end of the string.

Consider what you're doing in each case. In the former code snippet, you're declaring a character array capable of holding HOST_NAME_MAX -1 characters (1 for the null terminator). You then load some string data into that buffer via the call to gethostname and then print out the length of buffer by assigning it to a std::string object using std::string::operator= that takes a const char * . One of the effects of this is that it will change an internal size variable of std::string to be strlen of the buffer, which is not necessarily the same as HOST_NAME_MAX . A call to std::string::length simply returns that variable.

In the latter case, you're using the std::string constructor that takes a size and initial character to construct test . This constructor sets the internal size variable to whatever size you passed in, which is HOST_NAME_MAX . The fact that you then copy in some data to std::string s internal buffer has no bearing on its size variable. As with the other case, a call to the length() member function simply returns the size - which is HOST_NAME_MAX - regardless of whether or not the actual length of the underlying buffer is smaller than HOST_NAME_MAX .

As @MattMcNabb mentioned in the comments, you could fix this by:

test.resize( strlen(test.c_str()) );

Why might you want to do this? Consistency with the char buffer approach might be a reason, but another reason may be performance oriented. In the latter case you're not only outright setting the length of the string to HOST_NAME_MAX , but also its capacity (omitting the SSO for brevity), which you can find starting on line 242 of libstdc++'s std::string implementation . What this means in terms of performance is that even though only, say, 25 characters are actually in your test string, the next time you append to that string (via += , std::string::append ,etc), it's more than likely to have to reallocate and grow the string, as shown here , because the internal size and internal capacity are equal. Following @MattMcNabb's suggestion, however, the string's internal size is reduced down to the length of the actual payload, while keeping the capacity the same as before, and you avoid the almost immediate re-growth and re-copy of the string, as shown here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM