sizeof的工作原理如何?可变长度字符串数组的内存映射

时间:2011-11-03 15:06:32

标签: c sizeof

const char *pointerStr[]=
{
   "BEST123,      ",     // 0x00
   "Best2233,     ",     // 0x01
   "ABCDEFGH,     ",     // 0x02
   "123456,     ",     // 0x03
   "helloworld,     "     // 0x04
};
typedef struct
{
   char value;
   char name[40]; 
}StrInfo;

typedef struct
{
   int regMax;
   StrInfo info[60];   
} structNew;

void main()
{
  int i;
  structNew  pret;
for ( i=0;i<5;i++)
{     
  printf("PointerStr size of %dth %d \n",i,sizeof(pointerStr[i]));
  printf("pret size of %dth %d \n",i,sizeof(pret.info[i].name));
}
}

以上程序产生

的结果
PointerStr size of 0th 4 
pret size of 0th 40 
PointerStr size of 1th 4 
pret size of 1th 40 
PointerStr size of 2th 4 
pret size of 2th 40 
PointerStr size of 3th 4 
pret size of 3th 40 
PointerStr size of 4th 4 
pret size of 4th 40 

如果我想知道PointerStr中每个字符串的大小,那么如何找到它?是否只能使用strlen?我们还有其他方法吗?这个可变长度数组如何存储在内存中?  结果是becoz指针指针变量是指针变量,它的大小总是4.如果我错了,请纠正我。

4 个答案:

答案 0 :(得分:7)

C字符串的长度是隐式的:它取决于字符串中终止'\0'的位置,因此您需要像strlen这样的函数来确定字符串的长度。< / p>

sizeof'返回'的值由编译器通过查看数据的类型而不是数据本身来确定。

答案 1 :(得分:2)

你得到数组长度但只有char*指针的大小的原因是sizeof不是函数调用,因为它出现了,但实际上是在编译时(可变长度数组除外)。

您的代码举例说明了数组和指针之间的关键区别。在编译时,编译器确切知道您的数组的长度(40),因为它是静态大小的。另一方面,char*甚至不一定指向以null结尾的字符串,因此它返回指针的大小。

查找字符串长度的正确方法是使用strlen。但请注意,这将告诉您第一个空字节(\0)之前的字符数。它不会告诉你实际分配了多少内存(sizeof在返回40时正在做的事情。)

答案 2 :(得分:1)

sizeof 是一个编译器。它给出了数据的大小,如编译时所见。它与执行时的动态内存分配无关。因此sizeof(char*)sizeof(p)变量声明为char* p;通常是单词的大小(即32位处理器上的4,64位处理器上的8)并且无关使用动态分配,或者在程序运行时使用字符串的实际长度。

答案 3 :(得分:1)

sizeof为您提供传递给它的变量的大小(以字节为单位)。您正在将指针数组(指向字符串)传递给sizeof。 C中的数组“衰减”为指针,所以你得到的是指向指针数组中第一个元素的指针。

然后你正确地以字节为单位获得指针的大小(4字节= 32位地址总线)。

由于“数组衰减”规则,您无法通过该指针获取字符串文字的实际内存单元大小,原因与您无法通过指针获取数组的大小相同这个例子中的ptr:

char array[10] = "...";
char* ptr = &array;

解决方案是以不同的方式存储数组,您可以在数组上使用sizeof(如真正的2D数组),或者将所有数组大小存储在查找表中:

const size_t STRING_SIZES[] =
{
  sizeof("BEST123,      "),
  sizeof("Best2233,     "),
  sizeof("ABCDEFGH,     "),
  sizeof("123456,     "),
  sizeof("helloworld,     ")
};