Sab
Sab

Reputation: 533

How to find size of elements pointed by array of pointers?

Here is the code,

char const *words[] ={
        "Hello",
        "What are you doing",
        0
    };
    int size = sizeof(words[1]), totalSize = sizeof(words);

The totalSize is is having the values 24 but size is having value 8. I used gdb to get a run-time look, for the command p words[1] result is $1 = 0x40400f "What are you doing" so words[1] is considered as array by debugger, still sizeof() is considering it as pointer. I don't understand why that is.

Upvotes: 3

Views: 432

Answers (6)

Manjunath N
Manjunath N

Reputation: 1375

The initial box shows the base address of the string.

+----+    +-----+
|1000|--->|Hello|
+----+    +-----+
words[0]

+----+    +------------------+
|2000|--->|What are you doing|
+----+    +------------------+
words[1]

if you perform sizeof(words[0]), which is a pointer of type char const* and we all know that the size of the pointer remains the same for all data type usually 4, but in you case its 64 bit machine and hence you are getting 8 as a output.

Even the sizeof(words[1]) would fetch you 8 for the same reason.

Use a pointer to a pointer concept for fetching the words at that base address.

Upvotes: 0

barak manos
barak manos

Reputation: 30146

The fact that the debugger shows you the contents of the pointed string doesn't mean that the compiler refers to it as a statically allocated array (for which the sizeof operator can be applied "correctly").

You can retrieve those sizes (excluding null characters) using this piece of code:

int size = strlen(words[1]);
int totalSize = 0;
for (int i=0; words[i]!=0; i++)
    totalSize += strlen(words[i]);

You may as well get rid of that last element in the words array, and use this instead:

int size = strlen(words[1]);
int totalSize = 0;
for (int i=0; sizeof(words)/sizeof(*words); i++)
    totalSize += strlen(words[i]);

Upvotes: 2

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

You declared array words like

char const *words[]; 

It means that each element of the array has type char const * and sizeof( words[0] ) is equivalent to sizeof( char const * ) that is equal in your environment to 8 bytes. If you want to know the length of the string literal pointed to by pointer words[0] then you should use standard C function strlen declared in header <string.h>. For example

size_t length = strlen( words[0] );

Take into account that though all pointers in the array have the same size that is 8 bytes string literals pointed to by these pointers have different sizes.

Here is a demonstrative program

#include <stdio.h>
#include <string.h>

int main(void) 
{
    char const *words[] =
    {
        "Hello",
        "What are you doing",
        0
    };

    const char **p = words;

    for ( ; *p; ++p ) printf( "\"%s\": %zu\n", *p, strlen( *p ) );

    return 0;
}

The output is

"Hello": 5
"What are you doing": 18

The string literals themselves have types in C correspondingly

char [6] and char[19] because they include the terminating zero.

Upvotes: 1

haccks
haccks

Reputation: 106102

words is an array of char pointers. Therefore, its elements are of type pointers to char. words[1] is of type pointer to char not an array of char and that's why you are getting the size of pointer instead of the size of the string it points to.

How to find size of elements pointed by array of pointers?

In order to find the size of string that a pointer points to, you need to loop over it.

int size = 0;
char const *ptr = words[1];
while(ptr++) 
    size++;  

or use standard library function strlen

size_t size = strlen(words[1]);

Upvotes: 1

ouah
ouah

Reputation: 145899

words is an array of 3 pointers to (const) char.

So sizeof with the array operand will yield the accumulated size of the 3 pointers and sizeof of an array element will yield the size of one pointer.

Upvotes: 2

Martijn Courteaux
Martijn Courteaux

Reputation: 68907

That's because the sizeof() operator is being replaced by the result at compile time. It should give the same result for all sizeof(words[i]) if used in a loop for example, so also for sizeof(words[1]). So the compiler interprets this simply as a (64-bit) pointer.

Upvotes: 1

Related Questions