sizeof an array referenced by pointer 
Author Message
 sizeof an array referenced by pointer

zentara> I'm trying to figure out c pointers, but
zentara> this has me stumped.
zentara> What I can't figure out is why the last block
zentara> of code only returns 4 for the sizeof(ptr);
zentara> I thought it would return 25. ??

According to sizeof documentation:

/-----------------
| If the type of the operand is a variable length array type, the
| operand is evaluated; otherwise, the operand is not evaluated and the
| result is an integer constant.
\-----------------

Here, ptr is a pointer to a char, so sizeof ptr give the size of a
pointer to a char (4 bytes, on your system).

The same doc says also:

/-----------------
| When applied to an operand that has array type, the result is the
| total number of bytes in the array.
\-----------------

So, if you have used:

char array[25];

sizeof array would have returned 25.

But pointers are not arrays...

--
ric Jacoboni, n il y a 1329787866 secondes



Mon, 27 Dec 2004 07:37:25 GMT  
 sizeof an array referenced by pointer

Quote:

> I'm trying to figure out c pointers, but
> this has me stumped.
> What I can't figure out is why the last block
> of code only returns 4 for the sizeof(ptr);
> I thought it would return 25. ??
> ######################################################
> /* Demonstrates the use of malloc() to allocate storage */
> /* space for string data. */
> #include <stdio.h>
> #include <stdlib.h>
> char count, *ptr, *p;
> int i,j;

Why define them as global variables?

Quote:
> main()

int main( void )

Quote:
> {
> /* Allocate a block of 25 bytes. Test for success. */
> /* The exit() library function terminates the program. */
> ptr = malloc(25 * sizeof(char));
> if (ptr == NULL)
> {
> puts("Memory allocation error.");

You probably will need an additional '\n' at the end of the string...

Quote:
> exit(1);

exit( EXIT_FAILURE );

is probably better. And, please, start using indentation!

Quote:
> }
> /* Fill the string with values 65 through 90, */
> /* which are the ASCII codes for A-Z. */
> /* p is a pointer used to step through the string. */
> /* You want ptr to remain pointed at the start */
> /* of the string. */
> p = ptr;
> for (count = 65; count < 91 ; count++)
> *p++ = count;
> /* Add the terminating null character. */
> *p = '\0';

Oops, you wrote over the end of the array you malloc()ed! For count
running from 65 to 90 you would already need 26 characters, and adding
an additional '\0' doesn't make it any better ;-)

Quote:
> /* Display the string on the screen. */
> puts(ptr);
> printf("####################################\n");
> printf("%c\t",*ptr);
> printf("%d\n",*ptr);
> printf("####################################\n");
> printf("%c\t",ptr[0]);
> printf("%d\n",ptr[0]);
> printf("####################################\n");
> j=25;
> for(i=0;i <= j ;i++){
> printf("%c\t",ptr[i]);
> printf("%d\n",ptr[i]);
> }
> printf("####################################\n");
> j= sizeof(ptr);

ptr is a variable that is supposed to hold a pointer to a character
and your computer obviously needs 4 bytes to store such a pointer.
What you stored in ptr is the address of a memory region you
got from malloc - there is no information about how long the
memory region is. The sizeof() trick you are probably looking for
will only work on real arrays, i.e. if you have

int a[ ] = { 1, 2, 3, 4, 5, 6 };

or

int a[ 6 ];

"sizeof a" will return the amount of memory needed for the array,
i.e. 6 * sizeof( int ), because 'a' isn't a pointer (even though it
can be treated similarly in certain situations). But for pointers
this won't work. For malloc()ed memory you will have to do your own
bookkeeping if necessary.

It's easy to see why when you realize that the sizeof invocations are
dealt with during compilation, so the compiler can easily determine
how long 'a' is, but normally it has no chance to figure out how many
bytes you will be going to allocate somewhere in your program.

Quote:
> for(i=0;i <= j ;i++){
> printf("%c\t",ptr[i]);
> printf("%d\n",ptr[i]);
> }
> return 0;
> }

You forgot to free() the memory you allocated.

                                        Regards, Jens
--
      _  _____  _____

  _  | |  | |    | |          AG Moebius, Institut fuer Molekuelphysik
 | |_| |  | |    | |          Fachbereich Physik, Freie Universitaet Berlin
  \___/ens|_|homs|_|oerring   Tel: ++49 (0)30 838 - 53394 / FAX: - 56046



Mon, 27 Dec 2004 07:51:45 GMT  
 sizeof an array referenced by pointer

Quote:

> What I can't figure out is why the last block
> of code only returns 4 for the sizeof(ptr);
> I thought it would return 25. ??

[...]

Quote:
> char count, *ptr, *p;
[...]
> ptr = malloc(25 * sizeof(char));

The type of ptr is char *, so sizeof(ptr)==sizeof(char *)
regardless of what value (if any) you assign to ptr.
Likewise, sizeof(*ptr) is always sizeof(char), which is 1.
If you need to preserve the number 25, save it in another
variable.


Mon, 27 Dec 2004 07:59:18 GMT  
 sizeof an array referenced by pointer
Submitted by "zentara" to comp.lang.c:

Quote:
> Hi,
> I'm trying to figure out c pointers, but
> this has me stumped.
> What I can't figure out is why the last block
> of code only returns 4 for the sizeof(ptr);
> I thought it would return 25. ??

Well, you declared it as "char *ptr" and on your system a
pointer to a char is apparantly 4 bytes.

See e.g.

http://groups.google.com/groups
?as_q=sizeof%20length%20array&as_ugroup=cmop.lang.c%20
alt.comp.lang.learn.c-c%2b%2b

(URL cut by me)

--
Andreas K?h?ri
--------------------------------------------------------------
Stable, secure, clean, free:  www.netbsd.org



Mon, 27 Dec 2004 09:02:38 GMT  
 sizeof an array referenced by pointer

Quote:


> > I'm trying to figure out c pointers, but
> > this has me stumped.
> > What I can't figure out is why the last block
> > of code only returns 4 for the sizeof(ptr);
> > I thought it would return 25. ??
> > ######################################################
> > /* Demonstrates the use of malloc() to allocate storage */
> > /* space for string data. */
> > #include <stdio.h>
> > #include <stdlib.h>
> > char count, *ptr, *p;
> > int i,j;

> Why define them as global variables?

Why call them global variables? They are file scope identifiers with
external linkage. :-)

Quote:

> > main()

> int main( void )

> > {
> > /* Allocate a block of 25 bytes. Test for success. */
> > /* The exit() library function terminates the program. */
> > ptr = malloc(25 * sizeof(char));
> > if (ptr == NULL)
> > {
> > puts("Memory allocation error.");

> You probably will need an additional '\n' at the end of the string...

Why? puts() does that for you.

Quote:

> > exit(1);

> exit( EXIT_FAILURE );

> is probably better. And, please, start using indentation!

  Agreed. But let's explain /why/, shall we? Firstly, there are
    exactly three exit statuses (stati?) whose meaning is portable
      across all implementations: 0, EXIT_SUCCESS, and EXIT_FAILURE.
        In the absence of a good reason to use a particular value
          other than these three, it's best to stick to what is
            portable.
            Indentation
          shows
        the logical structure
      of your
    code.
  This paragraph is not a great example of why that's a good idea.

Quote:
> > }
> > /* Fill the string with values 65 through 90, */
> > /* which are the ASCII codes for A-Z. */
> > /* p is a pointer used to step through the string. */
> > /* You want ptr to remain pointed at the start */
> > /* of the string. */
> > p = ptr;
> > for (count = 65; count < 91 ; count++)
> > *p++ = count;
> > /* Add the terminating null character. */
> > *p = '\0';

> Oops, you wrote over the end of the array you malloc()ed! For count
> running from 65 to 90 you would already need 26 characters, and adding
> an additional '\0' doesn't make it any better ;-)

Furthermore, consider the effect of running this program on an EBCDIC
system.

<snip>

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton



Mon, 27 Dec 2004 16:24:36 GMT  
 sizeof an array referenced by pointer

    Others have explained your misunderstanding of `sizeof';
let me point out one other problem in your code:

Quote:
> ptr = malloc(25 * sizeof(char));

    This allocates enough space to hold 25 characters (if
successful, which you check for properly).

Quote:
> p = ptr;
> for (count = 65; count < 91 ; count++)
> *p++ = count;

    This deposits 26 characters in your 25-character region
of memory -- or, rather, it deposits 25 characters there
and then does Lord knows what with the 26th.

Quote:
> /* Add the terminating null character. */
> *p = '\0';

    ... and trying to store a 27th character in your 25-
character area is just adding insult to injury.

--



Mon, 27 Dec 2004 22:46:30 GMT  
 sizeof an array referenced by pointer
On Thu, 11 Jul 2002 17:31:07 -0400, in comp.lang.c , zentara

Quote:

>Would anyone care  to  critique this method?
>#include <stdio.h>
>#include <stdlib.h>
>char count, *ptr, *p;

there's no reason for these to be globals - put them inside main.

Quote:
>main (void)

int main(void) is required in ISO/ANSI conforming C

Quote:
>{
>   int i, j;
>   ptr = malloc (27 * sizeof (char));

sizeof(char) is one by definition, so you can simplify this
        ptr = malloc(27);

Quote:
>   if (ptr == NULL)
>     {
>        puts ("Memory allocation error.");
>        exit (EXIT_FAILURE);
>     }
>  p = ptr;
>  for (count = 65; count < 91; count++)
>     *p++ = count;

this might be easier to read if you did
  for(count=0;count<26;count++)
        *p++ = (count+65);

Quote:
>     *p = '\0';

for some reason this was indented to align with the line above? Sould
line up wit the line below.

Quote:
>  for (i = 0; ptr[i] != (char)NULL; i++)

don't use NULL for null characters - use '\0' or even just 0. NULL is
a null pointer, is not guaranteed to be equal to zero, and cannot
safely be converted into a char.

Quote:
>     {
>       printf ("%c\t", ptr[i]);
>       printf ("%d\n", ptr[i]);

pedantry says you should cast ptr[i] in the second line, to ensure
that printf sees it as an int and not a char.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>



Tue, 28 Dec 2004 06:18:01 GMT  
 sizeof an array referenced by pointer

Quote:

> Hi, thanks to all who helped me see this error. I've come up with a
> method  to access the ptr string as an array. Would anyone care
> to  critique this method? I needed to use a cast to char on the NULL
> to eliminate an error warning.  Is there a better way to do this?
> Is this totally wacko?
> #include <stdio.h>
> #include <stdlib.h>
> char count, *ptr, *p;
> main (void)

Please, main() is always returning an integer, so use

int main( void )

Quote:
> {
>    int i, j;
>    ptr = malloc (27 * sizeof (char));
>    if (ptr == NULL)
>      {
>         puts ("Memory allocation error.");
>         exit (EXIT_FAILURE);
>      }
>   p = ptr;
>   for (count = 65; count < 91; count++)
>      *p++ = count;
>      *p = '\0';
>   puts (ptr);
>   for (i = 0; ptr[i] != (char)NULL; i++)
>      {
>        printf ("%c\t", ptr[i]);
>        printf ("%d\n", ptr[i]);
>      }
>   printf ("%d\n", i);
>   return 0;
> }

You need to cast because you compare a character (that's what stored in
ptr[i]) with NULL, which often is defined as ( void * ) 0, so without the
cast you compare a character to a pointer. Simply replace the offending
line by

for ( i = 0; ptr[ i ] != '\0'; i++ )

and you don't need the cast anymore.

Quote:
> I guess I'm trying to see how to convert pointer character strings of
> arbitrary size to arrays.

You're not converting anything, you have a pointer to a char and no
arrays at all. You just use the fact that the compiler will convert

ptr[ i ]    to      * ( ptr + i )

so pointers can in some respect treated like arrays and vice versa.
Btw., you still forgot

free( ptr );

at the end of your program ;-)
                                        Regards, Jens
--
      _  _____  _____

  _  | |  | |    | |          AG Moebius, Institut fuer Molekuelphysik
 | |_| |  | |    | |          Fachbereich Physik, Freie Universitaet Berlin
  \___/ens|_|homs|_|oerring   Tel: ++49 (0)30 838 - 53394 / FAX: - 56046



Tue, 28 Dec 2004 06:18:46 GMT  
 sizeof an array referenced by pointer
Submitted by "zentara" to comp.lang.c:

Quote:


>>> I'm trying to figure out c pointers, but

>>"sizeof a" will return the amount of memory needed for the array,
>>i.e. 6 * sizeof( int ), because 'a' isn't a pointer (even though it
>>can be treated similarly in certain situations). But for pointers
>>this won't work. For malloc()ed memory you will have to do your own
>>bookkeeping if necessary.

> Hi, thanks to all who helped me see this error. I've come up with a
> method  to access the ptr string as an array. Would anyone care
> to  critique this method? I needed to use a cast to char on the NULL
> to eliminate an error warning.  Is there a better way to do this?
> Is this totally wacko?
> I guess I'm trying to see how to convert pointer character strings of
> arbitrary size to arrays.

> #include <stdio.h>
> #include <stdlib.h>
> char count, *ptr, *p;

No reason for them to be global.

Quote:

> main (void)

"int main(void)"

Quote:
> {
>    int i, j;
>    ptr = malloc (27 * sizeof (char));

You may leave sizeof(char) out as it is always 1.  Or replace it
by sizeof *ptr.

Quote:
>    if (ptr == NULL)
>      {
>         puts ("Memory allocation error.");
>         exit (EXIT_FAILURE);
>      }
>   p = ptr;
>   for (count = 65; count < 91; count++)
>      *p++ = count;
>      *p = '\0';

That indentation fooled me first.

I have never seen why peple wants to use the *p++ -way of
traversing an array. Is it more efficient?  I think it's just
hard to read.  I would have said

for (count = 0; count < 26; ++count) {
    ptr[count]=count+65;

Quote:
}

ptr[26]='\0';

That's easier to debug.

Quote:

>   puts (ptr);

>   for (i = 0; ptr[i] != (char)NULL; i++)

Why not '\0' instead of (char)NULL?

Quote:
>      {
>        printf ("%c\t", ptr[i]);
>        printf ("%d\n", ptr[i]);
>      }
>   printf ("%d\n", i);

free(ptr);

Quote:
>   return 0;
> }

--
Andreas K?h?ri
--------------------------------------------------------------
Stable, secure, clean, free:  www.netbsd.org


Tue, 28 Dec 2004 06:22:39 GMT  
 sizeof an array referenced by pointer

Quote:


>> main (void)

>Please, main() is always returning an integer, so use

>int main( void )

In your opinion, what was the OP's main definition returning?

The good argument for the explicit int in a function definition
(regardless of its name) is that C99 requires it.

Dan
--
Dan Pop
DESY Zeuthen, RZ group



Tue, 28 Dec 2004 19:29:56 GMT  
 sizeof an array referenced by pointer


Quote:
>On Thu, 11 Jul 2002 17:31:07 -0400, in comp.lang.c , zentara

>>main (void)

>int main(void) is required in ISO/ANSI conforming C

If you're telling people this, you should also tell them that there are
very few ISO/ANSI conforming C compilers currently available, and that
the version of C implemented by most current compilers allows return
types to default to int.
(It's also worth noting, while we're on the subject, that relying on
implicit int has been considered bad style for quite some time.)

dave

--

(In the interest of full disclosure, I do, however, have a friend
who is a rocket scientist.)
                                       --Ben Pfaff in comp.lang.c



Tue, 28 Dec 2004 21:30:20 GMT  
 sizeof an array referenced by pointer

Quote:



>>On Thu, 11 Jul 2002 17:31:07 -0400, in comp.lang.c , zentara

>>>main (void)

>>int main(void) is required in ISO/ANSI conforming C

>If you're telling people this, you should also tell them that there are
>very few ISO/ANSI conforming C compilers currently available,

Hu? I've never seen a compiler that was NOT ANSI aware since 1990.

Each and any ANSI standard requires main as

int main(void)
or
int main(int argc, char *argv[]);

main()
is outdated pre ANSI C only.

The only here that had changed with ANSI 99 is that closing main()
without a return statement defaults to return 0;

--
Tschau/Bye
        Herbert

http://www.pc-rosenau.de
the point to buy eComStation in germany



Wed, 29 Dec 2004 01:13:10 GMT  
 sizeof an array referenced by pointer

Quote:

>main()
>is outdated pre ANSI C only.

no, its perfectly legal C89, since c89 had implicit int. It was
deprecated but not illegal.

Quote:
>The only here that had changed with ANSI 99 is that closing main()
>without a return statement defaults to return 0;

that too
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


Wed, 29 Dec 2004 06:02:59 GMT  
 sizeof an array referenced by pointer

Quote:



>>> main (void)

>>Please, main() is always returning an integer, so use

>>int main( void )
> In your opinion, what was the OP's main definition returning?

I didn't claim he isn't returning an int, I was just asking him to make
it stand out clearly (you or even me may be the one that get the job of
maintaining  his programs some day) and I didn't tell him to use it
but was begging: "Please, do it this way" ;-)

Quote:
> The good argument for the explicit int in a function definition
> (regardless of its name) is that C99 requires it.

Of course, that's a much better reason for sure.

                                         Regards, Jens
--
      _  _____  _____

  _  | |  | |    | |          AG Moebius, Institut fuer Molekuelphysik
 | |_| |  | |    | |          Fachbereich Physik, Freie Universitaet Berlin
  \___/ens|_|homs|_|oerring   Tel: ++49 (0)30 838 - 53394 / FAX: - 56046



Wed, 29 Dec 2004 06:38:56 GMT  
 sizeof an array referenced by pointer

Quote:




>>>On Thu, 11 Jul 2002 17:31:07 -0400, in comp.lang.c , zentara

>>>>main (void)

>>>int main(void) is required in ISO/ANSI conforming C

>>If you're telling people this, you should also tell them that there are
>>very few ISO/ANSI conforming C compilers currently available,

>Hu? I've never seen a compiler that was NOT ANSI aware since 1990.

>Each and any ANSI standard requires main as

>int main(void)
>or
>int main(int argc, char *argv[]);

Or anything equivalent to one of these definitions.

Quote:
>main()
>is outdated pre ANSI C only.

Pray tell, what is the difference between main() and int main() in a
function definition, as far as ANSI C89 / ISO C90 is concerned?
Chapter and verse, please.

Quote:
>The only here that had changed with ANSI 99 is that closing main()
>without a return statement defaults to return 0;

Nope.  It is C99 that no longer supports the implicit int return type in
a function definition.

Dan
--
Dan Pop
DESY Zeuthen, RZ group



Fri, 31 Dec 2004 19:36:37 GMT  
 
 [ 16 post ]  Go to page: [1] [2]

 Relevant Pages 

1. sizeof and arrays/pointers question

2. how to modify a pointer to an array one sizeof(int)

3. Question on Pointer and Array reference

4. Trying to pass array of pointers to characters by reference

5. De-referencing a pointer to an array

6. forward reference a static array of function pointers

7. sizeof pointer to pointer

8. Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers

9. Array of pointers, pointer to array...

10. array pointer/pointer array

11. arrays pointers array of pointers

12. sizeof (pointer to array)/sizeof (p[0]) how to use ?

 

 
Powered by phpBB® Forum Software