473,796 Members | 2,586 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to get array size from a pointer?

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.
Oct 8 '08 #1
30 3616

<gg******@gmail .comwrote in message
news:37******** *************** ***********@o40 g2000prn.google groups.com...
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

Oct 8 '08 #2
On Oct 8, 4:11 pm, "ggngu...@gmail .com" <ggngu...@gmail .comwrote:
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.
Oct 8 '08 #3
On Oct 8, 4:22 pm, "Bartc" <b...@freeuk.co mwrote:
<ggngu...@gmail .comwrote in message

news:37******** *************** ***********@o40 g2000prn.google groups.com...
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.)
Bollocks. 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.

Oct 8 '08 #4
"gg******@gmail .com" <gg******@gmail .comwrites:
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.
Oct 8 '08 #5
On 8 okt, 15:11, "ggngu...@gmail .com" <ggngu...@gmail .comwrote:
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
Oct 8 '08 #6
Bartc wrote:
>
<gg******@gmail .comwrote in message
news:37******** *************** ***********@o40 g2000prn.google groups.com...
>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-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.
Oct 8 '08 #7

<vi******@gmail .comwrote in message
news:31******** *************** ***********@r37 g2000prr.google groups.com...
On Oct 8, 4:22 pm, "Bartc" <b...@freeuk.co mwrote:
><ggngu...@gmai l.comwrote in message

news:37******* *************** ************@o4 0g2000prn.googl egroups.com...
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

Oct 8 '08 #8
Bartc wrote:
>
<vi******@gmail .comwrote in message
news:31******** *************** ***********@r37 g2000prr.google groups.com...
>On Oct 8, 4:22 pm, "Bartc" <b...@freeuk.co mwrote:
....
>>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".
Oct 8 '08 #9
gg******@gmail. com <gg******@gmail .comwrote:
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
er******@studen t.uu.se
Oct 8 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

58
10186
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of code... TCHAR myArray; DoStuff(myArray);
1
6436
by: Sam | last post by:
Hello all I have a two dimensional array (the dimensions are not known) that needs to be passed to fortran from c++, allocate the dimensions of the array in fortran code, do some filling up of the array in fortran and then accessing it in my c++ code. Say in my c++ code I have; extern "C" { void foo_(float **, int &, int &); }
8
29070
by: Tweaxor | last post by:
Hey, I was trying to figure out was it possible in C to pass the values in an array from one function to another function. Is the possible in C? ex. y is the array that holds seven values If possible how could one pass these seven values in the array to a function that would check the values. I tried return y but it didn't work
6
4152
by: Herrcho | last post by:
in K&R Chapter 6.3 it mentions two methods to calculate NKEYS. and points out the first one which is to terminate the list of initializers with a null pointer, then loop along keytab until the end is found is less efficient than using sizeof operator , since size of the array is completely determined at compile time. i don't quite understand this. Could anyone explain to me in detail ?
7
7417
by: simkn | last post by:
Hello, I'm writing a function that updates an array. That is, given an array, change each element. The trick is this: I can't change any elements until I've processed the entire array. For example, the manner in which I update element 1 depends on several other (randomly numbered) elements in the array. So, I can't change an element until I've figured out how every element changes.
9
2199
by: shaun | last post by:
Dear all, I realized an error in a previous post, I reproduce it here because I'm still not sure how to solve it: I want to make a templated function which points to one-past-the-end of a simple array, to pass to a range constructor for a const vector. Here is some demonstration code: #include <iostream> using namespace std;
12
3888
by: gcary | last post by:
I am having trouble figuring out how to declare a pointer to an array of structures and initializing the pointer with a value. I've looked at older posts in this group, and tried a solution that looked sensible, but it didn't work right. Here is a simple example of what I'm trying to accomplish: // I have a hardware peripheral that I'm trying to access // that has two ports. Each port has 10 sequential // registers. Create a...
23
7421
by: sandy | last post by:
I need (okay, I want) to make a dynamic array of my class 'Directory', within my class Directory (Can you already smell disaster?) Each Directory can have subdirectories so I thought to put these in an array. The application compiles but aborts without giving me any useful information. What I suspect is happening is infinite recursion. Each Directory object creates an array of Subdirectories each of which has an array of...
7
8136
by: bowlderster | last post by:
Hello,all. I want to get the array size in a function, and the array is an argument of the function. I try the following code. /*************************************** */ #include<stdio.h> #include<stdlib.h> #include<math.h>
33
7188
by: Adam Chapman | last post by:
Hi, Im trying to migrate from programming in Matlab over to C. Im trying to make a simple function to multiply one matrix by the other. I've realised that C can't determine the size of a 2d array, so im inputting the dimensions of those myself. The problem is that the output array (C=A*B) has as many rows as A and as many columns as B. I would think of initialising C with:
0
9685
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10465
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10242
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10021
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9061
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7558
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6800
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5453
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
3
2931
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.