Sizeof in C++ Showing String Size One Less

sizeof in c++ showing string size one less

sizeof(s) gives you the size of the object s, not the length of the string stored in the object s.

You need to write this:

cout << s.size() << endl;

Note that std::basic_string (and by extension std::string) has a size() member function. std::basic_string also has a length member function which returns same value as size(). So you could write this as well:

cout << s.length() << endl;

I personally prefer the size() member function, because the other containers from the standard library such as std::vector, std::list, std::map, and so on, have size() member functions but not length(). That is, size() is a uniform interface for the standard library container class templates. I don't need to remember it specifically for std::string (or any other container class template). The member function std::string::length() is a deviation in that sense.

Sizeof string vs sizeof string pointer

The size of a pointer is always the size of the pointer itself, not what it points to. That's because sizeof is mostly a compile-time operator (the result is evaluated by the compiler) and the compiler can't know what a pointer might point to at run-time.

As for sizeof *title it's the same as sizeof title[0] which is a single char. And the size of a char is 1 (it's specified to always be 1 by the way, no matter the actual bit-width).

Lastly about sizeof "VP". In C all literal strings are really arrays of characters, including the terminating null character. So the literal string "VP" is an array of three characters, hence its size is 3.


To make the answer a little bit more complete, I say that the sizeof operator is mostly compile-time. That of course can't be true for variable-length arrays, where the compiler must insert code to store the actual size of the array in a way that it can be fetched at run-time. If the array decays to a pointer, then all you have is the pointer and again sizeof returns the size of the pointer itself.

And a note about string literal arrays. While they are technically non-constant arrays, they still can't be modified. Attempting to modify a string literal leads to undefined behavior. Literal strings are thus, in effect, read-only.

The size of a string

 char str[25];

Can only contain a string of 24 char + NULL. Use a width specifier to limit input to 1 less than buffer size when scanning strings into scanf().

Replace the if() branch with a while() loop:

length = stringLength(str);
while(length > 24)// an array of 25 elements can only accommodate 24 characters + NULL
{
printf("Invalid\n");
printf("Enter string: ");
//use input limiter of 24 for char str[25];
scanf("%24s", str);//remove & (for all scanf scanning a string)
length = stringLength(str);
}

When 'sizeof' is applied on a string, why does it return its size (as strlen)?

They are not the same string, or even the same type. char s2[] is an array, it has the size of the sum of the size of its elements. char *s2 is a pointer, it has the size of a pointer.

sizeof() is (in C89) a compile-time operator that must know the size of it's argument at compile time. Since a pointer can come from anywhere, sizeof() can't know the size of the allocated memory, but an array is always given a size at compile time (except for C99's VLA's), and sizeof() can then return the size of that memory.

reduce the size of a string

There are multiple problems in your code:

  • url[i] != "/" is incorrect, it is a type mismatch. You should compare the character url[i] with a character constant '/', not a string literal "/".

  • char *s = realloc(str, sizeof(char) + 1); reallocates only to size 2, not the current length plus 1.

  • you do not increase the pointers, neither do you use the index variable.

  • instead of using malloc and realloc, you should first compute the length of the server name and allocate the array with the correct size directly.

Here is a modified version:

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

char *read_website(const char *url) {
// skip the protocol part
if (!strncmp(url, "http://", 7))
url += 7;
else if (!strncmp(url, "https://", 8))
url += 8;
// compute the length of the domain name, stop at ':' or '/'
size_t n = strcspn(url, "/:");
// return an allocated copy of the substring
return strndup(url, n);
}

int main(void) {
char s[] = "http://www.wikipedia.org/";
char *str = read_website(s);
printf("%s -> %s\n", s, str);
free(str);
return 0;
}

strndup() is a POSIX function available on many systems and that will be part of the next version of the C Standard. If it is not available on your target, here is a simple implementation:

char *strndup(const char *s, size_t n) {
char *p;
size_t i;
for (i = 0; i < n && s[i]; i++)
continue;
p = malloc(i + 1);
if (p) {
memcpy(p, s, i);
p[i] = '\0';
}
return p;
}

Why does Sizeof operator on a std::string yield unexpected result?

sizeof of a std::string instance just returns the size, in bytes, of the "internal representation" of the std::string, i.e. you can think of it like the sum of the sizeofs of each std::string's data members (there may be padding involved as well).

For example, in 32-bit debug builds with VS2015, sizeof(std::string) returns 28; in 64-bit debug builds I get 40; in 32-bit release builds I get 24, and in 64-bit release builds 32.

That's because the internal representation of std::string changes with different build options: e.g. debug builds usually contain additional mechanics to help spotting bugs, which grows the size of the representation; moreover, in 64-bit builds the pointers are larger, so again the size increases with respect to 32-bit builds, etc.

So, the number you get from sizeof invoked on a std::string instance is in general different from the number of chars that make the string's text. To get this number, you have to call std::string::size or std::string::length.



Related Topics



Leave a reply



Submit