Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > How to get array size from a pointer?

Reply
Thread Tools

How to get array size from a pointer?

 
 
ggnguser@gmail.com
Guest
Posts: n/a
 
      10-08-2008
It's part of a test and I'm stumped. There is a function

void foo(char **x)

The function signature is given and cannot be changed, so no passing
of other values. The test case involves defining this variable:

char *y[] = { /* bunch of stuff */ }

and calling

foo(y)

In the above, "bunch of stuff" is a series of triplets, two strings
followed by a null string (""). However, the last triplet ends with an
integer 0. This seems that it's supposed to signify the end of the
array. However, it appears to me that 0 is the same binary value as
for the empty string (NUL, \0, whatever). So in effect, one cannot
test for it as a sentry value because it's actually the same as the
preceding triplets.

How then, can the function foo() determine the bounds of the array?
Knowing the bounds of the particular test case is not sufficient since
the actual test suite may have arrays of varying size.
 
Reply With Quote
 
 
 
 
Bartc
Guest
Posts: n/a
 
      10-08-2008

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> It's part of a test and I'm stumped. There is a function
>
> void foo(char **x)
>
> The function signature is given and cannot be changed, so no passing
> of other values. The test case involves defining this variable:
>
> char *y[] = { /* bunch of stuff */ }
>
> and calling
>
> foo(y)
>
> In the above, "bunch of stuff" is a series of triplets, two strings
> followed by a null string (""). However, the last triplet ends with an
> integer 0. This seems that it's supposed to signify the end of the
> array. However, it appears to me that 0 is the same binary value as
> for the empty string (NUL, \0, whatever). So in effect, one cannot
> test for it as a sentry value because it's actually the same as the
> preceding triplets.


Any empty string is not necessarily NULL.

{ "ABC","","GHI",0}

Three non-NULL strings followed by a NULL.

(vippstar will say NULL is not the same as 0. Whatever; if all you have to
mark the end is 0, then use it and hope that on your system 0 will never be
a legal string pointer.)

--
bartc

 
Reply With Quote
 
 
 
 
vippstar@gmail.com
Guest
Posts: n/a
 
      10-08-2008
On Oct 8, 4:11 pm, "(E-Mail Removed)" <(E-Mail Removed)> wrote:
> It's part of a test and I'm stumped. There is a function
>
> void foo(char **x)
>
> The function signature is given and cannot be changed, so no passing
> of other values. The test case involves defining this variable:
>
> char *y[] = { /* bunch of stuff */ }
>
> and calling
>
> foo(y)
>
> In the above, "bunch of stuff" is a series of triplets, two strings
> followed by a null string (""). However, the last triplet ends with an
> integer 0. This seems that it's supposed to signify the end of the
> array. However, it appears to me that 0 is the same binary value as
> for the empty string (NUL, \0, whatever). So in effect, one cannot
> test for it as a sentry value because it's actually the same as the
> preceding triplets.


char *y[] is an array of char * pointers. When a constant integer
expression with the value 0 appears in integer context, it becomes a
null pointer constant.
It's the same if you had written 0 or NULL.

> How then, can the function foo() determine the bounds of the array?
> Knowing the bounds of the particular test case is not sufficient since
> the actual test suite may have arrays of varying size.


Like strlen(); Strlen iterates until it encounters a byte whose value
is 0; Your function would iterate until it encounters a pointer whose
value is NULL.
 
Reply With Quote
 
vippstar@gmail.com
Guest
Posts: n/a
 
      10-08-2008
On Oct 8, 4:22 pm, "Bartc" <(E-Mail Removed)> wrote:
> <(E-Mail Removed)> wrote in message
>
> news:(E-Mail Removed)...
>
>
>
> > It's part of a test and I'm stumped. There is a function

>
> > void foo(char **x)

>
> > The function signature is given and cannot be changed, so no passing
> > of other values. The test case involves defining this variable:

>
> > char *y[] = { /* bunch of stuff */ }

>
> > and calling

>
> > foo(y)

>
> > In the above, "bunch of stuff" is a series of triplets, two strings
> > followed by a null string (""). However, the last triplet ends with an
> > integer 0. This seems that it's supposed to signify the end of the
> > array. However, it appears to me that 0 is the same binary value as
> > for the empty string (NUL, \0, whatever). So in effect, one cannot
> > test for it as a sentry value because it's actually the same as the
> > preceding triplets.

>
> Any empty string is not necessarily NULL.


An empty string is _never_ NULL.

> { "ABC","","GHI",0}
>
> Three non-NULL strings followed by a NULL.


What is a non-NULL string? A string can't be NULL! That doesn't make
sense.

> (vippstar will say NULL is not the same as 0. Whatever; if all you have to
> mark the end is 0, then use it and hope that on your system 0 will never be
> a legal string pointer.)


*******s. Don't put words in my mouth ever again.
0 can never be a "legal string pointer".
NULL is guaranteed to compare unequal to all addresses of objects.

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      10-08-2008
"(E-Mail Removed)" <(E-Mail Removed)> writes:

> It's part of a test and I'm stumped. There is a function
>
> void foo(char **x)
>
> The function signature is given and cannot be changed, so no passing
> of other values. The test case involves defining this variable:
>
> char *y[] = { /* bunch of stuff */ }
>
> and calling
>
> foo(y)
>
> In the above, "bunch of stuff" is a series of triplets, two strings
> followed by a null string (""). However, the last triplet ends with an
> integer 0. This seems that it's supposed to signify the end of the
> array. However, it appears to me that 0 is the same binary value as
> for the empty string (NUL, \0, whatever). So in effect, one cannot
> test for it as a sentry value because it's actually the same as the
> preceding triplets.


A little terminology: I'd call it a sentinel and I'd call "" an empty
string (I see you do to). "Null string" is just too confusing a term
to use safely.

Your question: when you write a string literal ("a", "hello", even "")
as an initialiser for a char * object, the characters in the string
are put into to an array somewhere (you don't need to care where) and
a pointer to that array is used as the value of the object. The array
is null-terminated: a byte with value zero is placed at the end.
Thus:

char *empty = "";

makes empty point to an array somewhere. That array need only contain
one character: a zero byte (sometimes called a null character).

C also permits any pointer to be set to a special value to show that
the pointer does not point to an object. This is a null pointer and
it quite different to a pointer that points to an array that happens
to start with a null character. Thus:

char *nowhere = 0;

makes nowhere a null pointer. You can also use the macro NULL if you
have included (one of) the right headers -- stddef.h for example.

Give a char pointer p, you can tell if it is a null pointer by asking:

if (p == 0) /* or p == NULL if you prefer */

In fact, simply writing

if (!p)

is enough but to tell if p points to an empty string, you must ask

if (*p == 0) /* or *p == '\0' if you prefer */

The same test can also be written p[0] == 0, !p[0] or simply !*p.

> How then, can the function foo() determine the bounds of the array?
> Knowing the bounds of the particular test case is not sufficient since
> the actual test suite may have arrays of varying size.


In short, it can't, but it can tell the difference between a null
pointer and a non-null pointer that points at a null character.

--
Ben.
 
Reply With Quote
 
Bart van Ingen Schenau
Guest
Posts: n/a
 
      10-08-2008
On 8 okt, 15:11, "(E-Mail Removed)" <(E-Mail Removed)> wrote:
> It's part of a test and I'm stumped. There is a function
>
> void foo(char **x)
>
> The function signature is given and cannot be changed, so no passing
> of other values. The test case involves defining this variable:
>
> char *y[] = { /* bunch of stuff */ }
>
> and calling
>
> foo(y)
>
> In the above, "bunch of stuff" is a series of triplets, two strings
> followed by a null string ("").


There is no such thing as a null string.
The string literal "" denotes an empty string, which is a string that
contains only the terminating '\0' character.

> However, the last triplet ends with an
> integer 0. This seems that it's supposed to signify the end of the
> array. However, it appears to me that 0 is the same binary value as
> for the empty string (NUL, \0, whatever). So in effect, one cannot
> test for it as a sentry value because it's actually the same as the
> preceding triplets.


First, the binary representation of a null pointer (what you get when
using 0 in a *pointer* context) is not required to be all-bits-zero
(although it often is).

The way you can detect if you are dealing with an empty string or a
null pointer is like this:
* Each string, including empty strings, has an address that is
distinct from NULL.
* When using strings, you are alweays passing around the addresses of
the strings.

>
> How then, can the function foo() determine the bounds of the array?
> Knowing the bounds of the particular test case is not sufficient since
> the actual test suite may have arrays of varying size.


If you iterate over x, then *x == NULL indicates the end of the array.
**x == '\0' indicates an empty string (if *x != NULL).

Bart v Ingen Schenau
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      10-08-2008
Bartc wrote:
>
> <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> It's part of a test and I'm stumped. There is a function
>>
>> void foo(char **x)
>>
>> The function signature is given and cannot be changed, so no passing
>> of other values. The test case involves defining this variable:
>>
>> char *y[] = { /* bunch of stuff */ }
>>
>> and calling
>>
>> foo(y)
>>
>> In the above, "bunch of stuff" is a series of triplets, two strings
>> followed by a null string (""). However, the last triplet ends with an
>> integer 0. This seems that it's supposed to signify the end of the
>> array. However, it appears to me that 0 is the same binary value as
>> for the empty string (NUL, \0, whatever). So in effect, one cannot
>> test for it as a sentry value because it's actually the same as the
>> preceding triplets.

>


> Any empty string is not necessarily NULL.


He wrote NUL, not NULL. NUL is the name for an ASCII character which is
written '\0' in C (when the character set is ASCII).

Referring to what you said, rather than what he was talking about:

NULL is necessarily not a an empty string. The only byte in an empty
string has a null character (NUL on ASCII systems). If NULL expands to
an expression with arithmetic type, it will certainly compare equal to
that null character; even if NULL has a pointer type, it will probably
compare equal to a null character on most systems - (void*)0 is required
to be a null pointer, but (void*)i is not required to produce the same
result, even if i==0 (though it usually does).

However, NULL will never compare equal to an empty string. An empty
string has a pointer type, and points at the array containing the null
character which terminates it. In any such comparison, NULL converts to
a null pointer of the same type, and a null pointer is prohibited from
comparing equal to any pointer to an actual object.

> { "ABC","","GHI",0}
>
> Three non-NULL strings followed by a NULL.
>
> (vippstar will say NULL is not the same as 0. ...


vippstar is correct. It could be (void*)0, or (8- or '\0', among many
other possibilities. They will all compare equal to 0, however.

> ... Whatever; if all you have
> to mark the end is 0, then use it and hope that on your system 0 will
> never be a legal string pointer.)


0 is a null pointer constant. When it appears in a pointer context, it
is treated as a null pointer. A null pointer can never compare equal to
a pointer to any actual object or pointer. It is legal for a system to
have a pointer whose bits are all 0 that is not a null pointer. However,
on such a system, such a pointer can NOT be produced by initializing a
pointer object with a null pointer constant.
 
Reply With Quote
 
Bartc
Guest
Posts: n/a
 
      10-08-2008

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On Oct 8, 4:22 pm, "Bartc" <(E-Mail Removed)> wrote:
>> <(E-Mail Removed)> wrote in message
>>
>> news:(E-Mail Removed)...
>>
>>
>>
>> > It's part of a test and I'm stumped. There is a function

>>
>> > void foo(char **x)

>>
>> > The function signature is given and cannot be changed, so no passing
>> > of other values. The test case involves defining this variable:

>>
>> > char *y[] = { /* bunch of stuff */ }

>>
>> > and calling

>>
>> > foo(y)

>>
>> > In the above, "bunch of stuff" is a series of triplets, two strings
>> > followed by a null string (""). However, the last triplet ends with an
>> > integer 0. This seems that it's supposed to signify the end of the
>> > array. However, it appears to me that 0 is the same binary value as
>> > for the empty string (NUL, \0, whatever). So in effect, one cannot
>> > test for it as a sentry value because it's actually the same as the
>> > preceding triplets.

>>
>> Any empty string is not necessarily NULL.

>
> An empty string is _never_ NULL.


I missed where the OP mentioned the null string "", and assumed that NULL
was also being used to signify an empty string.

However NULL to represent an empty string can be a useful technique
(although not recognised by standard functions), hence my comment.

>
>> { "ABC","","GHI",0}
>>
>> Three non-NULL strings followed by a NULL.

>
> What is a non-NULL string? A string can't be NULL! That doesn't make
> sense.


Isn't that what I said? A string that is not NULL.

>> (vippstar will say NULL is not the same as 0. Whatever; if all you have
>> to
>> mark the end is 0, then use it and hope that on your system 0 will never
>> be
>> a legal string pointer.)

>
> B?ll?cks.


So eloquent.

--
Bartc

 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      10-08-2008
Bartc wrote:
>
> <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> On Oct 8, 4:22 pm, "Bartc" <(E-Mail Removed)> wrote:

....
>>> Any empty string is not necessarily NULL.

>>
>> An empty string is _never_ NULL.

>
> I missed where the OP mentioned the null string "", and assumed that
> NULL was also being used to signify an empty string.
>
> However NULL to represent an empty string can be a useful technique
> (although not recognised by standard functions), hence my comment.


No, NULL can be used to represent a missing string. An empty string is a
string containing one null character; NULL does not qualify.

>>> { "ABC","","GHI",0}
>>>
>>> Three non-NULL strings followed by a NULL.

>>
>> What is a non-NULL string? A string can't be NULL! That doesn't make
>> sense.

>
> Isn't that what I said? A string that is not NULL.


But all strings are not NULL, so that's a pointless phrase. Just say
"Three strings followed by a null pointer".
 
Reply With Quote
 
Erik Trulsson
Guest
Posts: n/a
 
      10-08-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> wrote:
> It's part of a test and I'm stumped. There is a function
>
> void foo(char **x)
>
> The function signature is given and cannot be changed, so no passing
> of other values. The test case involves defining this variable:
>
> char *y[] = { /* bunch of stuff */ }
>
> and calling
>
> foo(y)
>
> In the above, "bunch of stuff" is a series of triplets, two strings
> followed by a null string (""). However, the last triplet ends with an
> integer 0. This seems that it's supposed to signify the end of the
> array. However, it appears to me that 0 is the same binary value as
> for the empty string (NUL, \0, whatever). So in effect, one cannot
> test for it as a sentry value because it's actually the same as the
> preceding triplets.
>
> How then, can the function foo() determine the bounds of the array?
> Knowing the bounds of the particular test case is not sufficient since
> the actual test suite may have arrays of varying size.


An empty string ("") is represented as a pointer to a NUL byte (i.e. a byte
that has the value 0)
(A string is a pointer to a character array that is terminated by a NUL byte)

A plain 0 interpreted as a pointer is a null pointer which is different.


If a particular entry compares equal to NULL then it is a null pointer
(which in your case would indicate the end of your array 'y' of char
pointers.) If it does not compare equal to NULL, but points to a byte having
the value 0, then it is an empty string. (The remaining possibilities are
that it points to a non-NULL string, or that it is an invalid pointer in
which case you did something wrong.)





--
<Insert your favourite quote here.>
Erik Trulsson
(E-Mail Removed)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Preferred Size, Minimum Size, Size Jason Cavett Java 5 05-25-2008 08:32 AM
mega pixels, file size, image size, and print size - Adobe Evangelists Frank ess Digital Photography 0 11-14-2006 05:08 PM
Could a struct with size 44 bytes point always points to a char array with size 2024 bytes? eagle_jyjh@citiz.net C++ 8 04-10-2006 03:05 PM
Could a struct with size 44 bytes point always points to a char array with size 2048 bytes? eagle_jyjh@citiz.net C Programming 5 04-09-2006 02:49 PM



Advertisments