sizeof an array referenced by pointer
Author |
Message |
Eric Jacobon #1 / 16
|
 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 |
|
 |
Jens.Toerr.. #2 / 16
|
 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 |
|
 |
Kalle Olavi Niemital #3 / 16
|
 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 |
|
 |
Andreas K?h? #4 / 16
|
 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 |
|
 |
Richard Heathfiel #5 / 16
|
 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 |
|
 |
Eric Sosma #6 / 16
|
 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 |
|
 |
Mark McIntyr #7 / 16
|
 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 |
|
 |
Jens.Toerr.. #8 / 16
|
 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 |
|
 |
Andreas K?h? #9 / 16
|
 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: "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 |
|
 |
Dan P #10 / 16
|
 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 |
|
 |
Dave Vandervi #11 / 16
|
 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 |
|
 |
Herbert Rosen #12 / 16
|
 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 |
|
 |
Mark McIntyr #13 / 16
|
 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 |
|
 |
Jens.Toerr.. #14 / 16
|
 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 |
|
 |
Dan P #15 / 16
|
 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 |
|
|
Page 1 of 2
|
[ 16 post ] |
|
Go to page:
[1]
[2] |
|