sizeof char* array in C/C++

2020-07-09 04:54发布

There are plenty of similar inquires, but in my case I don't understand what isn't working:

int mysize = 0;
mysize = sizeof(samplestring) / sizeof(*samplestring);
std::cout << mysize << '\n' << samplestring;

This outputs:

4

Press 'q' to quit.

How is it possible? 4 definitely isn't the size of this string. I even tried the following, with the same result:

mysize = sizeof(samplestring) / sizeof(samplestring[0]);

EDIT: Ok, this is the declaration:

char *samplestring = "Start."; 

I'm on C++, but I need to use functions that only accept char *. Later in the code I assign new strings to that variable, like:

samplestring = "Press 'r' for red text.";

Yes, the compiler gives me warnings, but I have no idea how can I use different strings if I can't overwrite them...

标签: c++ c sizeof
6条回答
▲ chillily
2楼-- · 2020-07-09 05:09

There are two ways of making a string constant, and your technique only works on the first one. The first one makes an array of characters which you can get the size of at compile time, and the other creates a pointer to an array of characters.

char samplestring[] = "hello";
char * samplestring = "hello";

Trying to take the size of the second case the way you're doing it just gives you the size of a pointer. On a 32-bit build the size of a pointer is 4 characters, i.e. a pointer takes the same amount of memory as 4 characters.

The following will always give the correct length for a properly null-terminated string, but it's slower.

mysize = strlen(samplestring);
查看更多
We Are One
3楼-- · 2020-07-09 05:17

4 isn't the size of the string, because samplestring isn't a string. It's a char*, whose size is (on your platform) 4, divided by 1 (size of char) is, correctly, 4.

In C++, you'd use std::string and the length() method.

In C, you'd use strlen which takes as parameter a NULL-terminated char pointer.

查看更多
霸刀☆藐视天下
4楼-- · 2020-07-09 05:18

The sizeof of an element returns the size of the memory allocated for that object. In your example the string is probably declared somewhere as

samplestring[4]

In which case the size of the memory is 4. The method you probably want in your application is

strlen(samplestring);

Which returns the size of the null terminated string (without the termination)

查看更多
姐就是有狂的资本
5楼-- · 2020-07-09 05:21

you are asking the size of a pointer on a char. So I guess you're using a 32bit system.

If you're using C++, use std::string :

std::string samplestring("Hello world");
std::cout << samplestring.size() << std::endl;
查看更多
虎瘦雄心在
6楼-- · 2020-07-09 05:29

First of all, sizeof(samplestring[0]) is the same as sizeof(*samplestring), they're both returning the size of the first element of the samplestring array. And, assuming samplestring is an array of chars, sizeof(char) is defined to be 1.

You haven't shown how samplestring is declared. It could be one of the following:

char const *samplestring = "Hello, World!";

or

char *samplestring = malloc( ... );

or

char samplestring[10];

In the first 2 cases the type of samplestring is char *, so sizeof(samplestring) returns sizeof(char *), which, on your platform is 4.

In the third case, the type of samplestring is char[10] (array of 10 chars), but if you call a function that takes a char * as its parameter, the char array will decay to a pointer pointing to the first element of the array. In this case, trying to print sizeof within the function will still result in the size of a pointer being printed.

If you want the size of the original array to be printed from within the function, then the function parameter needs to be a pointer to the original array type (and the type includes size of the original array).

#include <stdio.h>

void foo( char (*arr)[42] )
{
  printf( "%u", (unsigned)sizeof(*arr) );
}

int main()
{
  char arr[42];
  foo( &arr );

  return 0;
}  

Output:

42

This fixes the size of the array that can be passed to the function and is not desirable in a lot of cases. The only other solution is to keep track of the array yourself (or use strlen if you have a NULL terminated string).

查看更多
等我变得足够好
7楼-- · 2020-07-09 05:30

It looks as though you have a pointer, not an array. Arrays are converted to pointers when the program requires it, so you'd get:

size_t size(char * p) { // p is a pointer
    return sizeof(p) / sizeof(*p); // size of pointer
}

size_t size(char p[]) { // p is also a pointer        
    return sizeof(p) / sizeof(*p); // size of pointer
}

although, since sizeof (char) == 1, the division is redundant here; if the pointer were to a larger type, then you'd get a differently unexpected result.

In C++ (but obviously not C), you can deduce the size of an array as a template parameter:

template <typename T, size_t N>
size_t size(T (&)[N]) {
    return N;  // size of array
}

or you can use classes such as std::vector and std::string to keep track of the size.

In C, you can use strlen to find the length of a zero-terminated string, but in most cases you'll need to keep track of array sizes yourself.

查看更多
登录 后发表回答