C++ 如何获取char *(char数组)的真实长度和总长度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21022644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the real and total length of char * (char array)?
提问by herohuyongtao
For a char []
, I can easily get its length by:
对于 a char []
,我可以通过以下方式轻松获取其长度:
char a[] = "aaaaa";
int length = sizeof(a)/sizeof(char); // length=6
However, I cannot do like this to get the length of a char *
by:
但是,我不能这样做来获得 a 的长度char *
:
char *a = new char[10];
int length = sizeof(a)/sizeof(char);
because, I know, a
here is a pointer, such that length
here will be always be 4
(or something other in different systems).
因为,我知道,a
这是一个指针,因此length
这里将始终是4
(或其他系统中的其他东西)。
My question is that how can I get the length of a char *
afterwards? I know someone may challenge me that you already know its 10
because you just created it. I want to know this because this step of getting its length may come long long way from its creation and I don't want to come long long way back to check this number. Moreover, I also want to know its real length.
我的问题是我怎样才能得到 a 的长度char *
?我知道有人可能会挑战我说你已经知道它,10
因为你刚刚创建了它。我想知道这一点,因为获取其长度的这一步可能距离它的创建还有很长的路要走,我不想再回来检查这个数字。而且,我也想知道它的真实长度。
To be more specific
更具体
- how can I get its real
length=5
? - how can I get its total
length=10
?
- 我怎样才能得到它的真实
length=5
? - 我怎样才能得到它的总数
length=10
?
for the following example:
对于以下示例:
char *a = new char[10];
strcpy(a, "hello");
回答by Elias Van Ootegem
You can't. Not with 100% accuracy, anyway. The pointer has no length/size but its own. All it does is point to a particular place in memory that holds a char. If that char is part of a string, then you can use strlen
to determine what chars follow the one currently being pointed to, but that doesn't mean the arrayin your case is that big.
Basically:
你不能。无论如何,不是 100% 准确。指针没有长度/大小,只有它自己的. 它所做的只是指向内存中保存字符的特定位置。如果该字符是字符串的一部分,那么您可以使用strlen
来确定当前指向的字符后面是什么字符,但这并不意味着您的情况下的数组有那么大。
基本上:
A pointeris not an array, so it doesn't needto know what the size of the array is. A pointer can point to a single value, so a pointer can exist without there even being an array. It doesn't even care where the memory it points to is situated (Read only, heap or stack... doesn't matter). A pointer doesn't have a length other than itself. A pointer just is...
Consider this:
一个指针是不是一个数组,所以它并不需要知道数组的大小是什么。指针可以指向单个值,因此指针可以存在,甚至没有数组。它甚至不关心它所指向的内存位于何处(只读、堆或堆栈......无关紧要)。指针除了自身之外没有其他长度。一个指针就是......
考虑一下:
char beep = '\a';
void alert_user(const char *msg, char *signal); //for some reason
alert_user("Hear my super-awsome noise!", &beep); //passing pointer to single char!
void alert_user(const char *msg, char *signal)
{
printf("%s%c\n", msg, *signal);
}
A pointer can be a single char, as well as the beginning, end or middle of an array...
Think of chars as structs. You sometimes allocate a single struct on the heap. That, too, creates a pointer without an array.
指针可以是单个字符,也可以是数组的开头、结尾或中间……
将字符视为结构。您有时会在堆上分配单个结构。这也创建了一个没有数组的指针。
Using only a pointer, to determine how big an array it is pointing to is impossible. The closest you can get to it is using calloc
and counting the number of consecutive \0 chars you can find through the pointer. Of course, that doesn't work once you've assigned/reassigned stuff to that array's keys and it also fails if the memory just outsideof the array happens to hold \0
, too. So using this method is unreliable, dangerous and just generally silly. Don't. Do. It.
仅使用一个指针来确定它指向的数组有多大是不可能的。最接近它的是使用calloc
和计算可以通过指针找到的连续 \0 字符的数量。当然,一旦您将内容分配/重新分配给该数组的键,这将不起作用,并且如果数组外的内存也恰好保持\0
,它也会失败。所以使用这种方法是不可靠的,危险的,而且通常很愚蠢。别。做。它。
Another analogy:
Think of a pointer as a road sign, it points to Town X. The sign doesn't know what that town looks like, and it doesn't know or care (or can care) who lives there. It's job is to tell you where to find Town X. It can only tell you how far that town is, but not how big it is. That information is deemed irrelevant for road-signs. That's something that you can only find out by looking at the town itself, not at the road-signs that are pointing you in its direction
另一个类比:
将指针视为路标,它指向X 镇。标志不知道那个城镇是什么样子,也不知道或关心(或可以关心)住在那里的人。它的工作就是告诉你在哪里可以找到镇X。它只能告诉你那个城镇有多远,而不能告诉你它有多大。该信息被认为与道路标志无关。这是你只能通过查看城镇本身才能找到的东西,而不是指向它方向的路标
So, using a pointer the only thing you can do is:
所以,使用指针你唯一能做的就是:
char a_str[] = "hello";//{h,e,l,l,o,int length = sizeof(a)/sizeof(char);//sizeof char is guaranteed 1, so sizeof(a) is enough
}
char *arr_ptr = &a_str[0];
printf("Get length of string -> %d\n", strlen(arr_ptr));
But this, of course, only works if the array/string is \0-terminated.
但是,当然,这仅在数组/字符串以 \0 结尾时才有效。
As an aside:
作为旁白:
size_t length = sizeof(a)/sizeof(*a);//best use ptr's type -> good habit
is actually assigning size_t
(the return type of sizeof
) to an int
, best write:
实际上是将size_t
( 的返回类型sizeof
)分配给int
,最好写:
typedef struct {
char* ptr;
int size;
} my_array;
my_array malloc_array(int size)
{
my_array res;
res.ptr = (char*) malloc(size);
res.size = size;
return res;
}
void free_array(my_array array)
{
free(array.ptr);
}
Since size_t
is an unsigned type, if sizeof
returns bigger values, the value of length
might be something you didn't expect...
由于size_t
是无符号类型,如果sizeof
返回更大的值, 的值length
可能是您没想到的......
回答by Olotiar
If the char *
is 0-terminated, you can use strlen
如果以char *
0 结尾,则可以使用strlen
Otherwise, there is no way to determine that information
否则,无法确定该信息
回答by DarkDust
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 usestrlen(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.
如果您指向的内存指针
char *
表示一个 C 字符串(即,它包含以 0 字节标记其结尾的字符),您可以使用strlen(a)
.否则,您需要将长度存储在某处。实际上,指针只指向1
char
。但是我们可以把它当作指向数组的第一个元素来对待。由于该数组的“长度”未知,因此您需要将该信息存储在某处。
回答by Mike Seymour
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.
只给指针,你不能。您必须保持传递给的长度,new[]
或者更好地用于std::vector
跟踪长度并在完成后释放内存。
Note: this answer only addresses C++, not C.
注意:这个答案只针对 C++,而不是 C。
回答by Jarod42
- In C++:
- 在 C++ 中:
Just use std::vector<char>
which keep the (dynamic) size for you. (Bonus, memory management for free).
只需使用std::vector<char>
which 为您保留(动态)大小。(奖金,免费的内存管理)。
Or std::array<char, 10>
which keep the (static) size.
或者std::array<char, 10>
保持(静态)大小。
- In pure C:
- 在纯 C 中:
Create a structure to keep the info, something like:
创建一个结构来保存信息,例如:
size_t N = 10;
char *a = new char[N];
回答by Vlad from Moscow
char *a = new char[10];
My question is that how can I get the length of a char *
字符 *a = 新字符 [10];
我的问题是我怎样才能得到一个字符的长度 *
It is very simply.:) It is enough to add only one statement
很简单。:) 只加一个语句就够了
std::cout << "The size is " << N << std::endl;
Now you can get the size of the allocated array
现在你可以得到分配数组的大小
char a[] = "aaaaa";
int length = sizeof(a)/sizeof(char); // length=6
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.
许多人在这里提到了 C 标准函数 std::strlen。但它不返回字符数组的实际大小。它只返回存储的字符串文字的大小。
The difference is the following. if to take your code snippet as an example
区别如下。如果以您的代码片段为例
std::string s( "aaaaa" );
std::cout << s.length() << std::endl;
then std::strlen( a ) will return 5 instead of 6 as in your code.
然后 std::strlen( a ) 将返回 5 而不是您的代码中的 6 。
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.
所以结论很简单:如果您需要动态分配字符数组,请考虑使用 class std::string
。它有 methof size 和它的同义词长度,允许随时获取数组的大小。
For example
例如
std::string s;
s.resize( 10 );
std::cout << s.length() << std::endl;
or
或者
#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];
}
回答by barak manos
You can implement your own new
and delete
functions, as well as an additional get-size
function:
你可以实现你自己new
和delete
功能,以及一个附加get-size
功能:
char a[] = "aaaaa";
int len1 = sizeof(a)/sizeof(char); // length = 6
int len2 = sizeof(a); // length = 6;
Alternatively, you can override the new
and delete
operators in a similar manner.
或者,您可以以类似的方式覆盖new
和delete
运算符。
回答by Montaldo
So the thing with the sizeofoperator is that it returns you the amount of storage needed, in bytes, to store the operand.
所以sizeof运算符的问题是它返回存储操作数所需的存储量(以字节为单位)。
The amount of storage needed to store a char is always 1 byte. So the sizeof(char)
will always return 1.
存储字符所需的存储量始终为 1 个字节。所以sizeof(char)
总是会返回1。
char *a = new char[10];
int length = sizeof(a)/sizeof(char);
This is the same for both len1
and len2
because this division of 1 does not influence the equation.
这对两者都是一样的len1
,len2
因为除以 1 不会影响等式。
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.
len1
和len2
携带值 6的原因与字符串终止符有关'\0'
。这也是一个向长度添加另一个字符的字符。因此,您的长度将是 6 而不是您期望的 5。
#include <stdio.h>
#include <stdlib.h>
int
main ()
{
int arraySz;
char *a;
unsigned int *q;
for (arraySz = 5; arraySz <= 64; arraySz++) {
printf ("%02d - ", arraySz);
a = new char[arraySz];
unsigned char *p = (unsigned char *) a;
q = (unsigned int *) (a - 4);
printf ("%02d\n", (*q));
delete[] (a);
}
}
You already mentioned that the length turns out to be 4 here, which is correct. Again, the sizeofoperator 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.
您已经提到这里的长度结果是 4,这是正确的。同样,sizeof运算符返回操作数的存储量,在您的情况下它是一个 pointer a
。一个指针需要 4 个字节的存储空间,因此在这种情况下长度为 4。因为您可能将其编译为 32 位二进制文件。如果您创建了 64 位二进制文件,则结果将为 8。
This explanation might be here already be here. Just want to share my two cents.
这个解释可能已经在这里了。只想分享我的两分钱。
回答by Siddharth
This may sound Evil? and I haven't tested it, but how about initializing all values in an array at allocation to '\0'
and then using strlen()
? This would give you your so-called real valuesince it would stop counting at the first '\0'
it encounters.
这可能听起来很邪恶?我还没有测试过它,但是如何在分配时初始化数组中的所有值'\0'
然后使用strlen()
?这将为您提供所谓的真正价值,因为它会在第一次'\0'
遇到时停止计数。
Well, now that I think about it though, please don't Ever? do this. Unless, you want to land in a pile of dirty memory.
好吧,现在我想了想,请永远不要?做这个。除非,你想落入一堆肮脏的记忆中。
Also, for the allocated memory or the total memoryyou may use the following functions if your environment provides them:
此外,对于分配的内存或总内存,如果您的环境提供,您可以使用以下函数:
回答by sak
when new allocates an array, depending on the compiler (i use gnu c++), the word in front of the array contains information about the number of bytes allocated.
当 new 分配一个数组时,取决于编译器(我使用 gnu c++),数组前面的字包含有关分配的字节数的信息。
The test code:
测试代码:
05 - 19
06 - 19
07 - 19
08 - 19
09 - 19
10 - 19
11 - 19
12 - 19
13 - 27
14 - 27
15 - 27
16 - 27
17 - 27
18 - 27
19 - 27
20 - 27
21 - 35
22 - 35
23 - 35
24 - 35
25 - 35
26 - 35
27 - 35
28 - 35
29 - 43
30 - 43
31 - 43
32 - 43
33 - 43
34 - 43
35 - 43
36 - 43
37 - 51
38 - 51
39 - 51
40 - 51
41 - 51
42 - 51
43 - 51
44 - 51
45 - 59
46 - 59
47 - 59
48 - 59
49 - 59
50 - 59
51 - 59
52 - 59
53 - 67
54 - 67
55 - 67
56 - 67
57 - 67
58 - 67
59 - 67
60 - 67
61 - 75
62 - 75
63 - 75
64 - 75
on my machine dumps out:
在我的机器上转储:
##代码##I would not recommend this solution (vector is better), but if you are really desperate, you could find a relationship and be able to conclude the number of bytes allocated from the heap.
我不会推荐这个解决方案(向量更好),但如果你真的很绝望,你可以找到一个关系并能够得出从堆分配的字节数。