在C/C++中,sizeof char*数组是多少?

12

有很多类似的问题,但在我的情况下,我不明白哪里出了问题:

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

这将输出:

4

Press 'q' to quit.

怎么可能呢?4明显不是这个字符串的长度。我甚至尝试了以下代码,但结果相同:

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

编辑:好的,这是声明:

char *samplestring = "Start."; 

我正在使用C++,但需要使用只接受char*的函数。在代码后面,我会将新的字符串分配给该变量,例如:

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

是的,编译器会给我警告,但我不知道如果不能覆盖它们,我该如何使用不同的字符串...


10
samplestring 是如何声明的? - Coding Mash
samplestring 的定义在哪里? - phoxis
2
你成功地遗漏了最重要的信息! - user3458
字符串是字符数组,不是吗?如果它是一个数组,*p会给出第一个元素。您需要一个包装类来更正确地获取大小。我认为您的数组是qwe+NULL。 - huseyin tugrul buyukisik
我要重申之前的评论,但是真的 @Abalieno 吗?没有包括 sampleString 的定义?这个问题能被归档/移除吗,以便不会出现作为可能解决方案供像我这样有类似问题的人发现一个不完整的问题主体?浪费时间。 - skittlebiz
显示剩余3条评论
6个回答

16

4 不是字符串的大小,因为 samplestring 不是字符串。它是一个 char*,其大小在您的平台上为 4,除以 1(char 的大小),正确结果是 4。

在 C++ 中,您将使用 std::stringlength() 方法。

在 C 中,您将使用 strlen,该函数接受以 NULL 结尾的 char 指针作为参数。


有没有一个好的参考(例如网页),我可以在其中找到各种平台上char*的大小? - Pyderman

5

有两种方法可以创建字符串常量,而你的技术只适用于第一种方法。第一种方法创建了一个字符数组,你可以在编译时获取其大小,而另一种方法则创建了一个指向字符数组的指针。

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

尝试按照您当前的方式获取第二个案例的大小只会给出指针的大小。在32位构建中,指针的大小为4个字符,即指针占用与4个字符相同的内存量。下面的方法始终可以正确获取以空字符结尾的字符串的长度,但速度较慢。
mysize = strlen(samplestring);

2
注意(对于操作员):如果将第一个传递给函数,它将会衰减为指针,因此 sizeof 只有在相同的上下文中才能给出您期望的结果。 - Luchian Grigore
strlen很好。 - Skyfish

5
首先,sizeof(samplestring[0])sizeof(*samplestring) 是等价的,它们都返回samplestring数组的第一个元素的大小。假设samplestring是一个字符数组,那么sizeof(char)被定义为1。
你没有展示samplestring如何声明。它可能是以下几种情况之一:
char const *samplestring = "Hello, World!";

或者
char *samplestring = malloc( ... );

或者

char samplestring[10];

在前两种情况下,samplestring 的类型为 char *,因此 sizeof(samplestring) 返回的是 sizeof(char *),在您的平台上为4。
在第三种情况下,samplestring 的类型为char[10](10个字符的数组),但是如果调用一个以char *作为参数的函数,则字符数组将会 衰减为指向数组第一个元素的指针。在这种情况下,尝试在函数中打印sizeof仍然会导致打印指针大小。
如果您想要在函数内打印原始数组的大小,则函数参数需要是指向原始数组类型的指针(类型包括原始数组的大小)。
#include <stdio.h>

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

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

  return 0;
}  

输出:

42

这会限制可以传递到函数中的数组的大小,而在许多情况下并不理想。另一种解决方案是自己跟踪数组(或者如果您有一个以NULL结尾的字符串,则使用strlen)。


3

看起来你拥有一个指针,而不是一个数组。当程序需要时,数组会被转换为指针,所以你会得到:

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
}

尽管在此处除法是多余的,因为 sizeof(char) == 1,但如果指针指向较大的类型,则会得到不同的意外结果。在C ++(但显然不是C)中,您可以将数组的大小推断为模板参数:
template <typename T, size_t N>
size_t size(T (&)[N]) {
    return N;  // size of array
}

或者您可以使用像std::vectorstd::string这样的类来跟踪大小。

在C语言中,您可以使用strlen函数来查找以零结尾的字符串的长度,但在大多数情况下,您需要自己跟踪数组的大小。


0

你正在询问 char 指针的大小。所以我猜你正在使用 32 位系统。

如果你正在使用 C++,请使用 std::string:

std::string samplestring("Hello world");
std::cout << samplestring.size() << std::endl;

但是我被迫来回转换,那么我该如何将char *放入适当的C++字符串中,执行操作,然后再发送回char *? - Abalieno
std::string samplestring(your_c_string); samplestring.c_str(); std::string samplestring(你的C字符串); samplestring.c_str(); - Tristram Gräbener

0

sizeof操作符返回分配给该对象的内存大小。

在您的示例中,该字符串可能在某个地方声明为

samplestring[4]

在这种情况下,内存的大小为4。 您可能希望在应用程序中使用的方法是

strlen(samplestring);

返回空终止字符串的大小(不包括终止符)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接