Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How sizeof works ? Memory map for variable length array of strings

77 views
Skip to first unread message

knight

unread,
Nov 3, 2011, 11:26:04 PM11/3/11
to
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));
}
}

The above program produce the result of

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

If I want to know the size of each and every string in PointerStr then
how to find it? Is it possible only using strlen ? do we have some
other way ? How this variable length array is stored in memory ? The
result is becoz that pointerStr is pointer variable and its size is
always 4. Please correct me if I am wrong.
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

Cumaar

unread,
Nov 4, 2011, 1:52:32 PM11/4/11
to
> comp.lang.c.moderated - moderation address: c...@plethora.net -- you must
> have an appropriate newsgroups line in your header for your mail to be seen,
> or the newsgroup name in square brackets in the subject line.  Sorry.

Yes. you are right. The size is that of the pointer which is 4.

For finding the size of the string pointed by each of the pointers,
yes strlen would be the obvious option.

In a situation where strlen is forbid, go for a simple function call
that computes the size.

short strsz(char *ptr){
short sz = 0;

if(ptr == NULL) return 0;

while(ptr[sz] != '\n')
sz++;

return sz;
}

May be use it like this.

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

}

Hope i am tuned to your frequency.

BR
Kumaar

James Kuyper

unread,
Nov 4, 2011, 1:53:03 PM11/4/11
to
That looks reasonable. "sizeof expression" produces the same result as
"sizeof(type)", where "type" is the type of "expression". Since types
can always be determined by the compiler at compile time (unless they
involve variable length arrays (VLAs), but that's a more advanced
topic), a sizeof expression is normally replaced by the appropriate
constant at compile time.

In this case, pointerStr[i] has a type of char*, regardless of the value
of i. On you machine, sizeof(char*) is 4, which is pretty common.
pret.info[i].name has a type of char[40], regardless of the value of i,
and sizeof(char[40]) is guaranteed to be exactly 40, so that's why you
got the results that you did.

> If I want to know the size of each and every string in PointerStr then
> how to find it? Is it possible only using strlen ?

That's precisely what strlen() is for. There are other ways of getting
the same number, but there's no reason for using any of the other ways
if strlen() is already provided by the library (as it will be for any
hosted implementation of C).

> ... do we have some
> other way ? How this variable length array is stored in memory ?

Nothing you've written here is a VLA. I'll discuss VLA's below. For now,
I'll explain what's going on in your actual code.

Each of the string literals in your code, such as "123456, ", causes
an unnamed array to be statically allocated, big enough to store every
character in the string plus a terminating null character '\0'. The
string literal itself has a value which is a pointer to that the first
character of that array. In other words,

char * p = "123456, ";


Is functionally equivalent to

char unnamed_array[] = {'1', '2', '3', '4', '5', '6', ',',
' ', ' ', ' ', ' ', ' ', '\0'};
char *p = &unnamed_array;

As explained above, "sizeof p" is exactly equivalent to
"sizeof(char*)", giving a value of 4 on your system, which is apparently
not what you want. strlen(p), on the other hand, will use the pointer
value of p, which points at the first character of the unnamed array
storing the contents of the string literal. It will search forward,
starting at that point, until it finds the terminating null character.
It counts how often it has to increment the pointer during the search,
in this case, 12 times. That's the value it will return. Hopefully, that
is the number you want?

A VLA is something quite different. VLAs are a feature that was
introduced in C99. Here's an example:

void func(int length)
{
char vla[length];
...

When func is called, an array of char of the specified length is
allocated to store vla. Unlike normal sizeof expressions, "sizeof vla"
cannot be evaluated at compile time. It has the same value as
"sizeof(char[length])", which is simply "length", a value which cannot
be determined until the function has actually been called.
--
James Kuyper

Dag-Erling Smørgrav

unread,
Nov 4, 2011, 1:53:18 PM11/4/11
to
knight <vima...@gmail.com> writes:
> If I want to know the size of each and every string in PointerStr then
> how to find it? Is it possible only using strlen ?

Yes.

> do we have some other way ?

No.

> How this variable length array is stored in memory ?

There is no variable-length array in your program. There is a
fixed-length array of pointers. The fact that you did not specify a
length does not mean it is variable, just that you trust the compiler to
figure it out on its own.

> The result is becoz that pointerStr is pointer variable and its size
> is always 4.

Almost: pointerStr is an array of pointers, and you are applying the
sizeof operator to individual elements of that array, which are
pointers. Arrays and pointers are different things, although the name
of an array can often be used as if it were the name of a pointer.

DES
--
Dag-Erling Smørgrav - d...@des.no

Richard Damon

unread,
Nov 4, 2011, 1:53:33 PM11/4/11
to
Note that pointerStr[i] is a "char *" so the sizeof it is not dependent
on the length of the string.

pointerStr is NOT a "variable length array", but has its size not
explicitly declared, but determined by the number of initializers.

knight

unread,
Nov 10, 2011, 12:26:29 PM11/10/11
to
Thanks to all for the answers. It was very useful to me.

On Nov 4, 10:53 pm, Richard Damon <news.x.richardda...@xoxy.net>
wrote:
> comp.lang.c.moderated - moderation address: c...@plethora.net -- you must

Dag-Erling Smørgrav

unread,
Nov 10, 2011, 12:26:14 PM11/10/11
to
Cumaar <gku...@gmail.com> writes:
> short strsz(char *ptr){
> short sz = 0;
>
> if(ptr == NULL) return 0;
>
> while(ptr[sz] != '\n')
> sz++;
>
> return sz;
> }

This function does not return the length of the string; it returns the
position of the first newline character, and invokes undefined behavior
if the string does not contain one. I would also suggest using a wider
type than short. Semantically, the correct type to use is size_t.

DES
--
Dag-Erling Smørgrav - d...@des.no
0 new messages