关于c ++:如何获取char *(char数组)的实际长度和总长度? 您所在的位置:网站首页 数组指针的长度 关于c ++:如何获取char *(char数组)的实际长度和总长度?

关于c ++:如何获取char *(char数组)的实际长度和总长度?

2024-07-16 16:14| 来源: 网络整理| 查看: 265

对于char [],我可以通过以下方式轻松获得其长度:

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

但是,我不能这样通过以下方式获取char *的长度:

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

因为,我知道,这里的a是一个指针,所以这里的length始终是4(或其他系统中的其他值)。

我的问题是,我以后如何获得char *的长度? 我知道有人可能会挑战我,因为您刚刚创建了它,所以您已经知道它的10。 我想知道这一点,因为获取长度的这一步骤可能距离其创建已经很久了,我也不想花很长时间去检查这个数字。 而且,我也想知道它的真实长度。

更具体

如何获得其真正的length=5? 我怎样才能得到它的总length=10?

对于以下示例:

12char *a = new char[10]; strcpy(a,"hello"); 相关讨论 strlen? (..) 您无法获得其指向的指针数组的长度。您需要通过其他方式跟踪它。 @KillianDS-是的,当然。我可能误解了这个问题,这就是为什么我写评论。 @KirilKirov不会给出数组的长度。是的,但是只有在特殊情况下才可以。 @juanchopanza-是的,但是"我的问题是,我以后如何获取char *的长度"听起来有点误导-不清楚预期的结果是指针所指向的数组还是字符串的长度。 @OP:Google为什么不"获取字符数组的长度"?还是为什么不阅读有关字符串的初学者教程?这个问题真的很简单... 之前已经有人回答过,指针不保存有关它指向的数据块大小(如果它指向数组)的信息,只是它在内存中的起始位置。 @KirilKirov同意,"字符长度*"不是很清楚。 您可以使用std::vector,因此具有大小,并且可以为您完成内存管理 尽管在C语言中使用vectors无效,但会损害可移植性:p,但还是个好主意! @Siidheesh-我不同意。首先,问题是关于C ++的,其次-您仍然可以从vector中获取char*。另外,如果您真的想在C和C ++之间实现"可移植性",则意味着-仅使用C(即使在这种情况下,也不是100%"可移植") 如果有解决此问题的方法,我认为传递数组的长度会过时。 只需抛出一个内存集将内存位置清零,使用strlen和bob yer叔叔xD @herohuyongtao a ="hello"在很多方面都是错误的。.但是至少编辑使问题更清楚了。 您能决定您要使用哪种语言吗?如果它是C,则不能使用new;如果是C ++,则应使用vector之类的更高级别的抽象来解决此问题。 @MikeSeymour我删除了C标签b / c,因为它说这不是C问题,我希望我早些注意到。 除非另有要求,否则要旨是将数组结构显式声明为数组,因为数组很容易折叠成指针,但指针不能成为数组。 您可能也对std::array感兴趣。 由于C标签已经添加了几次,因此我标记了问题,我们将让mod来 这个问题似乎不合时宜,因为它与C字符串有关,任何C或C ++编程书籍都会告诉您。 找到了一个有趣的花絮,请访问stackoverflow.com/questions/437150/了解更多信息。

你不能无论如何,不??是100%的准确性。指针没有长度/大小,而是自己的。它所做的全部只是指向内存中包含char的特定位置。如果该char是字符串的一部分,则可以使用strlen确定在当前指向的char后面跟随哪些char,但这并不意味着您的情况下的数组那么大。 基本上:

指针不是数组,因此不需要知道数组的大小。指针可以指向单个值,因此即使没有数组,指针也可以存在。它甚至都不在乎它所指向的内存在哪里(只读,堆或堆栈...都没有关系)。指针的长度不等于自身。指针就是... 考虑一下:

123456789char 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\ ", msg, *signal); }

指针可以是单个字符,也可以是数组的开始,结尾或中间... 将字符视为结构。您有时会在堆上分配一个结构。这也将创建一个没有数组的指针。

仅使用指针来确定指向的数组是不可能的。最接近它的是使用calloc并计算可以通过指针找到的连续\ 0字符的数量。当然,一旦您为该数组的键分配了东西,该操作就不会起作用,并且如果该数组外部的内存也恰好容纳了\\0,它也将失败。因此,使用这种方法是不可靠,危险的,而且通常很愚蠢。别。做。它。

另一个比喻: 可以将指针视为一个路标,它指向X镇。该标志不知道该镇的样子,也不知道或关心(或可以关心)那里的人。要做的是告诉您在哪里可以找到X镇。它只能告诉您该镇有多远,但不能告诉它有多大。该信息被认为与道路标志无关。您只能通过查看城镇本身(而不是指向您的方向的路标)来了解

因此,使用指针唯一可以做的是:

1234char a_str[] ="hello";//{h,e,l,l,o,\\0} char *arr_ptr = &a_str[0]; printf("Get length of string -> %d\ ", strlen(arr_ptr));

但是,这当然仅在数组/字符串以\ 0结尾的情况下有效。

作为旁白:

1int length = sizeof(a)/sizeof(char);//sizeof char is guaranteed 1, so sizeof(a) is enough

实际上是将size_t(sizeof的返回类型)分配给int,最好这样写:

1size_t length = sizeof(a)/sizeof(*a);//best use ptr's type -> good habit

由于size_t是无符号类型,因此如果sizeof返回更大的值,则length的值可能是您没想到的...

相关讨论 @herohuyongtao:使用指针,您无法获得最大长度。片段中的new char[10]中分配了10个字符,并将指针分配给a。您可以在strcpy之后使用strlen(a),并返回5,但不可能得到10,除非您执行char *a = calloc(10, sizeof *a);之类的操作,否则在for(i=0;a[i] == \\0;++i);之后,i-1可以给出总长度如果分配的内存旁边的内存也不会意外地容纳\\0,则这是危险和糟糕的。但是您使用C ++:使用std::string或std::vector 出于好奇,a [0] == 0 [a] == * a不是吗?为什么使用sizeof(* a)比使用sizeof(a [0])更好的习惯?除非您的意思是它比单独使用sizeof(a)更好... @Siidheesh:严格来说是a[0] == 0[a] == *(a+0),但是使用sizeof *a的主要原因是在使用除char之外的其他类型或自定义分配器中使用指向指针的指针时。考虑void my_alloc(void **ptr, size_t size) { (*ptr) = malloc(size*sizeof(*(*ptr)));}这在分配结构,整数,字符...任何类型时都可以使用,而sizeof(type)则需要您知道该类型。 @APerson:我的意思是说使用sizeof *a比使用sizeof 更好,并且比sizeof a更好(这并不总是您想要的)。就个人而言,我也碰巧更喜欢*a而不是a[0],这仅仅是因为它很清楚(IMHO)指针已被取消引用。在检查代码或查找段错误原因时,这些行是我的第一个调用端口。当我看到a[0]时,可能(错误地)认为a是局部数组变量,而不是NULL指针

如果char *以0终止,则可以使用strlen

否则,无法确定该信息

相关讨论 strlen不能可靠地给出数组的长度。 @Olotiar除非您使用特定的编译器并找到与分配的内存有关的数据的存储位置(毕竟,为了使内存分配正常工作,为该特定位置分配的内存量需要存储在某个位置,因此不会与另一个分配重叠,因此free将正常工作)。 strlen不计算\\0。 @JAB这是一个很好的说明,尽管我不知道访问该信息的任何标准方法。 @JAB仅在动态分配的情况下仍然有效。 对于我的示例(更新),如何获得10作为strlen只能获得5? 你不能。使用前哨(特殊分隔符),int记住长度,定制结构或更高级别的结构,例如c ++中的std::vector @MarounMaroun然后为\\0添加+1。通过简单地保存指针的一个副本并逐渐增加它直到达到\\0,也可以自己进行计数。当然,需要确保该字符串实际上是\\0终止的。这里需要弄清楚的另一件事是,必须使用malloc或其他某种方法来获取连续的内存块。否则,指针的增量可能会落在存储来自其他内容的信息的块中,从而导致获取垃圾数据或崩溃。

只有两种方法:

如果char *指向的内存指针表示一个C字符串(也就是说,它包含带有0字节标记其结尾的字符),则可以使用strlen(a)。

否则,您需要将长度存储在某个地方。实际上,指针仅指向一个char。但是我们可以将其视为指向数组的第一个元素。由于该数组的"长度"未知,因此您需要将该信息存储在某个地方。

在C ++中:

只需使用std::vector即可为您保留(动态)尺寸。 (奖金,免费的内存管理)。

或std::array保持(静态)大小。

在纯C中:

创建一个结构来保留信息,例如:

1234567891011121314151617typedef 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); }

仅给出指针,就不能。您必须保持传递给new[]的长度,或者更好的是,使用std::vector来跟踪长度,并在完成时释放内存。

注意:此答案仅针对C ++,而不针对C。 sub>

相关讨论 假设他只使用C ++。如果代码也需要作为C程序工作,那么不幸的是std::vector不会有太大帮助。 @JAB:哦,是的,我刚刚注意到问题是同时询问两种语言。我希望人们不要这样做。 如果他使用new,则不能使用C。 @JohnDibling是的,但该问题同时被标记为C++和C(尽管现在不再存在)。

因此,使用sizeof运算符的事情是,它以字节为单位返回存储操作数所需的存储量。

存储char所需的存储量始终为1个字节。因此sizeof(char)将始终返回1。

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

len1和len2都是一样的,因为1的除法不会影响方程式。

len1和len2都携带值6的原因与字符串终止char '\\0'有关。这也是一个字符,它增加了另一个字符的长度。因此,您的长度将是6,而不是您预期的5。

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

您已经提到长度在此处为4,这是正确的。再次,sizeof运算符返回操作数的存储量,在您的情况下,它是指针a。指针需要4个字节的存储空间,因此在这种情况下长度为4。由于您可能将其编译为32位二进制文??件。如果您创建了64位二进制文??件,则结果为8。

这种解释可能已经在这里。只想分享我的两分钱。

您可以实现自己的new和delete函数,以及附加的get-size函数:

123456789101112131415161718192021222324252627#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]; }

另外,您可以类似的方式覆盖new和delete运算符。

相关讨论 为创造力+1,尽管我不建议在实际应用中这样做。您还必须实现复制和调整大小。使用C ++时,有更好的方法来解决该问题。

char *a = new char[10];

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

这很简单。:)仅添加一条语句就足够了

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

现在您可以获得分配的数组的大小

1std::cout


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有