Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #42458 > unrolled thread

array-size/malloc limit and strlen() failure

Started byjay <arnuld.mizong@gmail.com>
First post2014-04-01 23:31 -0700
Last post2014-04-03 00:33 -0500
Articles 20 on this page of 26 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  array-size/malloc limit and strlen() failure jay <arnuld.mizong@gmail.com> - 2014-04-01 23:31 -0700
    Re: array-size/malloc limit and strlen() failure Xavier Roche <xroche@free.fr.NOSPAM.invalid> - 2014-04-02 08:47 +0200
    Re: array-size/malloc limit and strlen() failure Kaz Kylheku <kaz@kylheku.com> - 2014-04-02 07:36 +0000
    Re: array-size/malloc limit and strlen() failure "BartC" <bc@freeuk.com> - 2014-04-02 10:10 +0100
      Re: array-size/malloc limit and strlen() failure Keith Thompson <kst-u@mib.org> - 2014-04-02 08:11 -0700
        Re: array-size/malloc limit and strlen() failure glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-04-02 19:03 +0000
          Re: array-size/malloc limit and strlen() failure James Kuyper <jameskuyper@verizon.net> - 2014-04-02 15:48 -0400
            Re: array-size/malloc limit and strlen() failure Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-02 14:42 -0700
              Re: array-size/malloc limit and strlen() failure Keith Thompson <kst-u@mib.org> - 2014-04-02 15:14 -0700
          Re: array-size/malloc limit and strlen() failure Keith Thompson <kst-u@mib.org> - 2014-04-02 14:55 -0700
            Re: array-size/malloc limit and strlen() failure glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-04-02 23:42 +0000
    Re: array-size/malloc limit and strlen() failure Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-02 02:34 -0700
    Re: array-size/malloc limit and strlen() failure James Kuyper <jameskuyper@verizon.net> - 2014-04-02 07:40 -0400
      Re: array-size/malloc limit and strlen() failure Thomas Jahns <jahns@idontlikespam.dkrz.de> - 2014-04-02 13:52 +0200
      Re: array-size/malloc limit and strlen() failure Keith Thompson <kst-u@mib.org> - 2014-04-02 08:21 -0700
        Re: array-size/malloc limit and strlen() failure James Kuyper <jameskuyper@verizon.net> - 2014-04-02 11:30 -0400
        Re: array-size/malloc limit and strlen() failure glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-04-02 19:26 +0000
          Re: array-size/malloc limit and strlen() failure "BartC" <bc@freeuk.com> - 2014-04-02 20:39 +0100
          Re: array-size/malloc limit and strlen() failure Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2014-04-02 14:39 -0600
          Re: array-size/malloc limit and strlen() failure Keith Thompson <kst-u@mib.org> - 2014-04-02 15:03 -0700
            Re: array-size/malloc limit and strlen() failure Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-03 01:11 -0700
              Re: array-size/malloc limit and strlen() failure Ike Naar <ike@iceland.freeshell.org> - 2014-04-03 14:27 +0000
                Re: array-size/malloc limit and strlen() failure James Kuyper <jameskuyper@verizon.net> - 2014-04-03 17:56 -0400
              Re: array-size/malloc limit and strlen() failure Keith Thompson <kst-u@mib.org> - 2014-04-03 08:18 -0700
                Re: array-size/malloc limit and strlen() failure gazelle@shell.xmission.com (Kenny McCormack) - 2014-04-03 15:30 +0000
        Re: array-size/malloc limit and strlen() failure Stephen Sprunk <stephen@sprunk.org> - 2014-04-03 00:33 -0500

Page 1 of 2  [1] 2  Next page →


#42458 — array-size/malloc limit and strlen() failure

Fromjay <arnuld.mizong@gmail.com>
Date2014-04-01 23:31 -0700
Subjectarray-size/malloc limit and strlen() failure
Message-ID<73748137-ca58-4518-b00d-86d886b3228b@googlegroups.com>
#include <stdio.h>
#include <limits.h>

int main(void)
{
 char arrc[UINT_MAX] = {'a'};
 printf("arrc = %s\n", arrc);

 return 0;
}

================ OUTPUT ==============
[myhome]$ gcc -ansi -pedantic -Wall -Wextra test2.c
test2.c: In function `main':
test2.c:6: error: size of array `arrc' is too large
test2.c:6: warning: unused variable `arrc'


I am using gcc 3.4.6 on Solaris 10.  I completely understand the error that array size should be below some limit but what is that limit ?  Same happens if I try to malloc(UINT_MAX), it fails.

2nd, I am writing a program where input is taken from command-line (think argv[1]). User can input anything of any size. Imagine user inputs a string too long, just like UINT_MAX was way bigger for malloc(), and I try to do strlen() on it ?  How will I know/check that string is too long so that I can bail out on time ?

I read about strlen() in C standard (n1570) in 6.24.6.3, it does not have any error condition associated with it.

[toc] | [next] | [standalone]


#42459

FromXavier Roche <xroche@free.fr.NOSPAM.invalid>
Date2014-04-02 08:47 +0200
Message-ID<lhgbp5$877$1@news.httrack.net>
In reply to#42458
On 04/02/2014 08:31 AM, jay wrote:
>   char arrc[UINT_MAX] = {'a'};

You have no guarantee that such size can be provided by a compiler. As 
far as I know, there is no "minimal" array size a compiler (and 
operating system) has to support.

> I am using gcc 3.4.6 on Solaris 10.  I completely understand the error that array size should be below some limit but what is that limit ?

When allocating on the *stack* (like here), the limit can vary (typical 
value in a created thread is few megabytes), but it is strongly advised 
not to put anything "large" on stack (because the size is limited, and 
failing to allocate will probably raise a signal when reaching the guard 
page)

> Same happens if I try to malloc(UINT_MAX), it fails.

It does not fail with me (64-bit, no ulimit, plenty of ram). It depends 
on the operating system, the available memory / virtual space, etc.

> 2nd, I am writing a program where input is taken from command-line (think argv[1]). User can input anything of any size. Imagine user inputs a string too long, just like UINT_MAX was way bigger for malloc(), and I try to do strlen() on it ?  How will I know/check that string is too long so that I can bail out on time ?

Program argument size are generally limited (typically 32K on many 
systems), and I do not see any practical case where you may end up with 
very long arguments. This case won't happen in the real world (because 
it is not possible to inject too long arguments in a program as far as I 
know).

For strlen(), yes, you can have a string whose size is at most SIZE_MAX 
(hypothetical case one more time, due to virtual space limit etc.)

A real-world case is a huge mmap'ed text file whose length would be 
computed using strlen(). Yes, it may take ages. Rewrite your own 
"strnlen" function if necessary...

[toc] | [prev] | [next] | [standalone]


#42460

FromKaz Kylheku <kaz@kylheku.com>
Date2014-04-02 07:36 +0000
Message-ID<20140402002802.249@kylheku.com>
In reply to#42458
On 2014-04-02, jay <arnuld.mizong@gmail.com> wrote:
> #include <stdio.h>
> #include <limits.h>
>
> int main(void)
> {
>  char arrc[UINT_MAX] = {'a'};
>  printf("arrc = %s\n", arrc);
>
>  return 0;
> }
>
>================ OUTPUT ==============
> [myhome]$ gcc -ansi -pedantic -Wall -Wextra test2.c
> test2.c: In function `main':
> test2.c:6: error: size of array `arrc' is too large
> test2.c:6: warning: unused variable `arrc'

You do realize that on a system with 32 bit pointers and 32 bit unsigned int,
"char [UINT_MAX]" takes up the entire address space?

Are you compiling a 64 bit executable or 32 bit?

Four billion byte arrays call for 64 bit programming on a 64 bit OS.

> I am using gcc 3.4.6 on Solaris 10.  I completely understand the error that
> array size should be below some limit but what is that limit ?  Same happens
> if I try to malloc(UINT_MAX), it fails.
> 2nd, I am writing a program where input is taken from command-line (think
> argv[1]). User can input anything of any size. Imagine user inputs a string
> too long, just like UINT_MAX was way bigger for malloc(), and I try to do
> strlen() on it ?  How will I know/check that string is too long so that I can
> bail out on time ?

The operating system imposes a limit on the total amont of memory which can be passed from one
process to another as environment variables and argument material.

The user will run into that argument passing limit long before we worry about
UINT_MAX sized arrays for a single argument string.

If an argv[1] could be prepared and passed to your program that is four billion
bytes long, strlen should work on it just fine.

[toc] | [prev] | [next] | [standalone]


#42461

From"BartC" <bc@freeuk.com>
Date2014-04-02 10:10 +0100
Message-ID<vvQ_u.132442$o%7.101937@fx29.am4>
In reply to#42458
"jay" <arnuld.mizong@gmail.com> wrote in message 
news:73748137-ca58-4518-b00d-86d886b3228b@googlegroups.com...

> int main(void)
> {
> char arrc[UINT_MAX] = {'a'};

> I am using gcc 3.4.6 on Solaris 10.  I completely understand the error 
> that array size should be below some limit but what is that limit ?  Same 
> happens if I try to malloc(UINT_MAX), it fails.

Why do you need a 4 billion-char array?

> 2nd, I am writing a program where input is taken from command-line (think 
> argv[1]). User can input anything of any size. Imagine user inputs a 
> string too long, just like UINT_MAX was way bigger for malloc(), and I try 
> to do strlen() on it ?  How will I know/check that string is too long so 
> that I can bail out on time ?

Is the idea that you allocate a 4294967296-char array just in case someone 
types something in that long (which would take several years of constantly 
holding down a key)? If so then stop worrying about it (it will be checked, 
or something will break, long before it gets to your program).

> I read about strlen() in C standard (n1570) in 6.24.6.3, it does not have 
> any error condition associated with it.

I doubt strlen will do much error checking, and I don't see how it can. It 
will expect the input to be well-formed, that is, it expects to encounter a 
0-byte before it hits the end of the memory block, and before it wraps the 
address space. It can't know the size of the memory block, and it would be 
too slow to keep checking that it runs out of address space as well as 
looking for a zero byte.

However, you can write your own strlen() function which takes some of that 
into account, if you're that paranoid about it (although beware that if the 
address space is 64-bits, wrap-around might be impossible).

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#42471

FromKeith Thompson <kst-u@mib.org>
Date2014-04-02 08:11 -0700
Message-ID<ln38hvhiku.fsf@nuthaus.mib.org>
In reply to#42461
"BartC" <bc@freeuk.com> writes:
[...]
> I doubt strlen will do much error checking, and I don't see how it can. It 
> will expect the input to be well-formed, that is, it expects to encounter a 
> 0-byte before it hits the end of the memory block, and before it wraps the 
> address space. It can't know the size of the memory block, and it would be 
> too slow to keep checking that it runs out of address space as well as 
> looking for a zero byte.
>
> However, you can write your own strlen() function which takes some of that 
> into account, if you're that paranoid about it (although beware that if the 
> address space is 64-bits, wrap-around might be impossible).

You can't *portably* write such a strlen() function.  There is no
portable way to tell whether a given non-null address is valid or not.

In any case, strlen isn't the problem here.  If you can allocate an
array and ensure that it contains a null byte somewhere, you can run
strlen on it.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#42481

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-04-02 19:03 +0000
Message-ID<lhhmud$5hc$1@speranza.aioe.org>
In reply to#42471
Keith Thompson <kst-u@mib.org> wrote:

(snip, someone wrote)
>> However, you can write your own strlen() function which takes some of that 
>> into account, if you're that paranoid about it (although beware that if the 
>> address space is 64-bits, wrap-around might be impossible).
 
> You can't *portably* write such a strlen() function.  There is no
> portable way to tell whether a given non-null address is valid or not.

Hmm. You can check to see if p++ is less than p. If that happens before
you find the '\0' in the string, you should probably stop looking.
 
> In any case, strlen isn't the problem here.  If you can allocate an
> array and ensure that it contains a null byte somewhere, you can run
> strlen on it.

-- glen

[toc] | [prev] | [next] | [standalone]


#42488

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-04-02 15:48 -0400
Message-ID<533C6997.4020404@verizon.net>
In reply to#42481
On 04/02/2014 03:03 PM, glen herrmannsfeldt wrote:
> Keith Thompson <kst-u@mib.org> wrote:
> 
> (snip, someone wrote)
>>> However, you can write your own strlen() function which takes some of that 
>>> into account, if you're that paranoid about it (although beware that if the 
>>> address space is 64-bits, wrap-around might be impossible).
>  
>> You can't *portably* write such a strlen() function.  There is no
>> portable way to tell whether a given non-null address is valid or not.
> 
> Hmm. You can check to see if p++ is less than p. ...

That depends upon whether you evaluate 'p' before or after evaluating
p++, and the most obvious way of checking that condition leaves that
order unspecified (it also has undefined behavior, for a different but
closely related reason). You can avoid both problems with a temporary:

	char *q = p;
        if( p++ < q) ...

but in that case the normal result is p==q. How about:

        char *q = p++;
        if(q < p) ...

but in that case, q == p - 1 is the normal result. I think you didn't
express the condition properly; or perhaps you were thinking of ++p
rather than p++?

> ... If that happens before
> you find the '\0' in the string, you should probably stop looking.

That test won't help you if p wanders into a protected block of memory.
Also, when handled properly, that test will fail only after the behavior
of p++ is already undefined, and in that case it's already too late. A
test that could be performed while the code implementing the test still
has defined behavior would be better.

[toc] | [prev] | [next] | [standalone]


#42491

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2014-04-02 14:42 -0700
Message-ID<d862f9d4-d888-4502-97f4-e566a2c42226@googlegroups.com>
In reply to#42488
On Wednesday, April 2, 2014 8:48:39 PM UTC+1, James Kuyper wrote:
> On 04/02/2014 03:03 PM, glen herrmannsfeldt wrote:
> 
> > Keith Thompson <kst-u@mib.org> wrote:
> 
> > 
> 
> > (snip, someone wrote)
> 
> >>> However, you can write your own strlen() function which takes some of that 
> 
> >>> into account, if you're that paranoid about it (although beware that if the 
> 
> >>> address space is 64-bits, wrap-around might be impossible).
> 
> >  
> 
> >> You can't *portably* write such a strlen() function.  There is no
> 
> >> portable way to tell whether a given non-null address is valid or not.
> 
> > 
> 
> > Hmm. You can check to see if p++ is less than p. ...
> 
> 
> 
> That depends upon whether you evaluate 'p' before or after evaluating 
> p++, and the most obvious way of checking that condition leaves that
> order unspecified (it also has undefined behavior, for a different but
> closely related reason). You can avoid both problems with a temporary:
> 
You could hold on to the pointer passed, then compare it with your
temporary travelling pointer. If it compares as equal, wrap-round has
occurred.

[toc] | [prev] | [next] | [standalone]


#42496

FromKeith Thompson <kst-u@mib.org>
Date2014-04-02 15:14 -0700
Message-ID<lnvbure5ur.fsf@nuthaus.mib.org>
In reply to#42491
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Wednesday, April 2, 2014 8:48:39 PM UTC+1, James Kuyper wrote:
>> On 04/02/2014 03:03 PM, glen herrmannsfeldt wrote:
>> > Keith Thompson <kst-u@mib.org> wrote:
>> > (snip, someone wrote)
>> >>> However, you can write your own strlen() function which takes
>> >>> some of that into account, if you're that paranoid about it
>> >>> (although beware that if the address space is 64-bits,
>> >>> wrap-around might be impossible).
>> >  
>> >> You can't *portably* write such a strlen() function.  There is no
>> 
>> >> portable way to tell whether a given non-null address is valid or not.
>> > 
>> > Hmm. You can check to see if p++ is less than p. ...
>> 
>> That depends upon whether you evaluate 'p' before or after evaluating 
>> p++, and the most obvious way of checking that condition leaves that
>> order unspecified (it also has undefined behavior, for a different but
>> closely related reason). You can avoid both problems with a temporary:
>> 
> You could hold on to the pointer passed, then compare it with your
> temporary travelling pointer. If it compares as equal, wrap-round has
> occurred.

And how do you know pointers "wrap around" under ++?  I wrote
above that you can't *portably* write such a strlen() function.
Do you disagree?  Keep in mind that incrementing a pointer just
past the end of an array has undefined behavior.

Perhaps it can be done if you have detailed knowledge about the memory
layout and addressing scheme of the current platform -- but you could
still get false negatives if, for example, an array with no '\0' happens
to be immediately followed in memory by another array that does have a
'\0'.

For example:

    char s0[4] = "abcd"; // no terminating '\0'
    char s1[4] = "def";

If s1 happens to immediately follow s0 in memory, strlen(s0) will likely
return 7 rather than reporting an error -- unless your implementation
uses fat pointers.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#42494

FromKeith Thompson <kst-u@mib.org>
Date2014-04-02 14:55 -0700
Message-ID<ln8urnflc0.fsf@nuthaus.mib.org>
In reply to#42481
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> wrote:
>
> (snip, someone wrote)
>>> However, you can write your own strlen() function which takes some of that 
>>> into account, if you're that paranoid about it (although beware that if the 
>>> address space is 64-bits, wrap-around might be impossible).
>  
>> You can't *portably* write such a strlen() function.  There is no
>> portable way to tell whether a given non-null address is valid or not.
>
> Hmm. You can check to see if p++ is less than p. If that happens before
> you find the '\0' in the string, you should probably stop looking.

Do you mean if p+1 is less than p?  If it is (and, in many cases, even
if it isn't), then just evaluating p+1 has undefined behavior.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#42499

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-04-02 23:42 +0000
Message-ID<lhi79n$cst$1@speranza.aioe.org>
In reply to#42494
Keith Thompson <kst-u@mib.org> wrote:

(snip)
>>> You can't *portably* write such a strlen() function.  There is no
>>> portable way to tell whether a given non-null address is valid or not.

(snip, then I wrote)
>> Hmm. You can check to see if p++ is less than p. If that happens before
>> you find the '\0' in the string, you should probably stop looking.
 
> Do you mean if p+1 is less than p?  If it is (and, in many cases, even
> if it isn't), then just evaluating p+1 has undefined behavior.

Yes, I was thinking about this later (while riding my bike down
the street) that p+1 would have been a better test. 

But yes, it is already undefined behavior. Even so, it is nicer
undefined behavior than the infinite loop that you otherwise might
run into. 

-- glen

[toc] | [prev] | [next] | [standalone]


#42462

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2014-04-02 02:34 -0700
Message-ID<0b49b8d1-2993-43ae-a026-3607a0c16772@googlegroups.com>
In reply to#42458
On Wednesday, April 2, 2014 7:31:47 AM UTC+1, jay wrote:
> #include <stdio.h>
> #include <limits.h>
> 
> int main(void)
> {
>  char arrc[UINT_MAX] = {'a'};
>  printf("arrc = %s\n", arrc);
>  return 0;
> 
> }
> 
> I am using gcc 3.4.6 on Solaris 10.  I completely understand the error that array size should be below > some limit but what is that limit ?  Same happens if I try to malloc(UINT_MAX), it fails.
>
It's very system dependent. memory is getting cheaper all the time, and systems with many gigabytes 
of ram are now common. However stacks are designed to be small, they grow logarithmically with
program complexity. You shouldn't put big items on the stack. Whilst it's hard to say what the limit
should be, 1024 doubles (8k) is a sort of ballpark. Anything bigger than that should be malloced.

malloc() either gives you the memory or it doesn't. If it doesn't, your computer isn't big enough to
handle that particular program with that dataset, and there's nothing you can do other than rewrite
the algorithm, or buy a bigger computer. 
>
> 2nd, I am writing a program where input is taken from command-line (think argv[1]). User can
> input anything of any size. Imagine user inputs a string too long, just like UINT_MAX was way 
> bigger for malloc(), and I try to do strlen() on it ?  How will I know/check that string is too long 
> so that I can bail out on time ?
> 
> I read about strlen() in C standard (n1570) in 6.24.6.3, it does not have any error condition associated > with it.
>
strlen steps through the string one character at a time, looking for a nil. As long as size_t has been
properly defined, it's impossible for the string to be too long for it. Even if string takes up 4GB,
strlen will return in three or four seconds on a typical 3Ghz system.

[toc] | [prev] | [next] | [standalone]


#42463

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-04-02 07:40 -0400
Message-ID<lhgsuq$aet$1@dont-email.me>
In reply to#42458
On 04/02/2014 02:31 AM, jay wrote:
> #include <stdio.h>
> #include <limits.h>
> 
> int main(void)
> {
>  char arrc[UINT_MAX] = {'a'};
>  printf("arrc = %s\n", arrc);
> 
>  return 0;
> }
> 
> ================ OUTPUT ==============
> [myhome]$ gcc -ansi -pedantic -Wall -Wextra test2.c
> test2.c: In function `main':
> test2.c:6: error: size of array `arrc' is too large
> test2.c:6: warning: unused variable `arrc'
> 
> 
> I am using gcc 3.4.6 on Solaris 10.  I completely understand the
> error that array size should be below some limit but what is that
> limit ?  Same happens if I try to malloc(UINT_MAX), it fails.

The standard imposes no specific limit. The closest it comes to doing so
is in section 5.2.4.1, which says that an "... implementation shall be
able to translate and execute at least one program that ...", among
other things, contains  "65535 bytes in an object (in a hosted
environment only)". Freestanding implementations, which often have very
small amounts of memory, are exempted from even this minimal
requirement. In principle, this clause renders then entire standard
nearly useless, since this is the ONLY program that implementation is
required to be able to translate and execute, and it's probably not your
program.

However, 5.2.4.1 is generally treated as if it imposed somewhat stronger
requirements than it actually does. This isn't entirely unreasonable -
for instance, if an implementation has a fixed upper limit on the size
of an object, 5.2.4.1p1 implies that this limit must be >= 65535.

A good general rule is that you should worry about the feasibility of
defining any object with a size greater than 65535. In some cases, it's
perfectly feasible to define objects on the stack with millions and even
billions of bytes; in other cases, the total available memory might be
barely sufficient for a single object of 65535 bytes. The only way to be
sure on any given systems is to try it.

> 2nd, I am writing a program where input is taken from command-line
> (think argv[1]). User can input anything of any size. Imagine user
> inputs a string too long, just like UINT_MAX was way bigger for
> malloc(), and I try to do strlen() on it ?  How will I know/check
> that string is too long so that I can bail out on time ?

As long as you're using a conforming implementation of C, you're
guaranteed that argc is non-negative and <= INT_MAX,  argv[argc] is a
null pointer, and argv[i] for 0 <= i && i < argc points at a null
terminated string. On any sane implementation, none of the strings will
have a size larger than can be reported by strlen(), which is SIZE_MAX
(#defined in <stdint.h>); but that's not actually required.

> I read about strlen() in C standard (n1570) in 6.24.6.3, it does not
> have any error condition associated with it.

Correct, strlen() provides no way of reporting errors. There's only one
possible error: passing it a pointer to a block of memory that is not
terminated by a null character. strlen() will continue looking for
characters until it reaches the end of that block of memory - what it
does after that point depends upon how your system works; as far as the
C standard is concerned, the behavior is simply undefined.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#42464

FromThomas Jahns <jahns@idontlikespam.dkrz.de>
Date2014-04-02 13:52 +0200
Message-ID<lhgtln$o07$1@gwdu112.gwdg.de>
In reply to#42463
On 04/02/14 13:40, James Kuyper wrote:
> A good general rule is that you should worry about the feasibility of
> defining any object with a size greater than 65535. In some cases, it's
> perfectly feasible to define objects on the stack with millions and even
> billions of bytes; in other cases, the total available memory might be
> barely sufficient for a single object of 65535 bytes. The only way to be
> sure on any given systems is to try it.

One problem here though is that for todays multi-threaded environments the limit
depends on which thread a function is called in and what limits on them were
imposed by the user or system configuration (things like ulimit -s or the
KMP_STACKSIZE environment variable). I therefore often advocate against putting
anything of truly variable size (e.g. depending on some input parameter) on the
stack, things that are sometimes of length 8 and sometimes length 12 are
perfectly fine unless really tight memory requirements are in place.

Thomas

[toc] | [prev] | [next] | [standalone]


#42472

FromKeith Thompson <kst-u@mib.org>
Date2014-04-02 08:21 -0700
Message-ID<lny4zng3jh.fsf@nuthaus.mib.org>
In reply to#42463
James Kuyper <jameskuyper@verizon.net> writes:
> On 04/02/2014 02:31 AM, jay wrote:
[...]
>> I read about strlen() in C standard (n1570) in 6.24.6.3, it does not
>> have any error condition associated with it.
>
> Correct, strlen() provides no way of reporting errors. There's only one
> possible error: passing it a pointer to a block of memory that is not
> terminated by a null character. strlen() will continue looking for
> characters until it reaches the end of that block of memory - what it
> does after that point depends upon how your system works; as far as the
> C standard is concerned, the behavior is simply undefined.

There are other possible errors: Passing it a null pointer, and
passing it an invalid non-null pointer.

Implementations of strlen are not required to detect any of these
errors; they all have undefined behavior.  (It would be easy to
detect a null pointer argument, but the overhead might be an issue,
and on most systems it's likely to cause a run-time fault anyway
-- and it's not clear what it should return for a null pointer
argument anyway.)

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#42473

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-04-02 11:30 -0400
Message-ID<533C2D03.5000406@verizon.net>
In reply to#42472
On 04/02/2014 11:21 AM, Keith Thompson wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
...
>> Correct, strlen() provides no way of reporting errors. There's only one
>> possible error: passing it a pointer to a block of memory that is not
>> terminated by a null character. strlen() will continue looking for
>> characters until it reaches the end of that block of memory - what it
>> does after that point depends upon how your system works; as far as the
>> C standard is concerned, the behavior is simply undefined.
> 
> There are other possible errors: Passing it a null pointer, and
> passing it an invalid non-null pointer.

You're right.  I knew about those, of course, but didn't think of them
while composing that message.

[toc] | [prev] | [next] | [standalone]


#42484

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-04-02 19:26 +0000
Message-ID<lhho8t$9e2$1@speranza.aioe.org>
In reply to#42472
Keith Thompson <kst-u@mib.org> wrote:
> James Kuyper <jameskuyper@verizon.net> writes:

(snip)
>> Correct, strlen() provides no way of reporting errors. There's only one
>> possible error: passing it a pointer to a block of memory that is not
>> terminated by a null character. 

(snip)
> There are other possible errors: Passing it a null pointer, and
> passing it an invalid non-null pointer.

Seems to me that there are two different types of systems
to consider. Those where the NULL pointer is actually addressable,
and those where it isn't.

On protected mode x86, segment selector zero is reserved by the
hardware. That is, the hardware knows about a NULL pointer.

On some systems, the null pointer is addressable, but outside the
user's address space. It might be that you can read it, but not
write it. When you do read it, it may or may not look like a '\0'.

I have known some systems (that didn't do any memory protection)
to test for writes to NULL by testing the value stored there at
the end of a program. (Better late than never.) In this case, you
can read and write to NULL.

> Implementations of strlen are not required to detect any of these
> errors; they all have undefined behavior.  (It would be easy to
> detect a null pointer argument, but the overhead might be an issue,
> and on most systems it's likely to cause a run-time fault anyway
> -- and it's not clear what it should return for a null pointer
> argument anyway.)

I suppose 0 and -1 are not so unreasonable choices. 

-- glen

[toc] | [prev] | [next] | [standalone]


#42486

From"BartC" <bc@freeuk.com>
Date2014-04-02 20:39 +0100
Message-ID<BIZ_u.119622$XE4.77423@fx26.am4>
In reply to#42484
"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message 
news:lhho8t$9e2$1@speranza.aioe.org...
> Keith Thompson <kst-u@mib.org> wrote:

>> Implementations of strlen are not required to detect any of these
>> errors; they all have undefined behavior.  (It would be easy to
>> detect a null pointer argument, but the overhead might be an issue,
>> and on most systems it's likely to cause a run-time fault anyway
>> -- and it's not clear what it should return for a null pointer
>> argument anyway.)
>
> I suppose 0 and -1 are not so unreasonable choices.

0 is a valid return value for strlen. I suppose you can also return it for a 
NULL pointer, but such a pointer is likely to run into more problems later 
on.

-1 might also be problematical when strlen returns an unsigned value.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#42490

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2014-04-02 14:39 -0600
Message-ID<1b4n2bpitc.fsf@snowball.wb.pfeifferfamily.net>
In reply to#42484
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> wrote:
>
>> Implementations of strlen are not required to detect any of these
>> errors; they all have undefined behavior.  (It would be easy to
>> detect a null pointer argument, but the overhead might be an issue,
>> and on most systems it's likely to cause a run-time fault anyway
>> -- and it's not clear what it should return for a null pointer
>> argument anyway.)
>
> I suppose 0 and -1 are not so unreasonable choices. 

A story I've told on myself before -- on a VAX running BSD, byte 0 was
readable and always contained 0.  For years I thought a null pointer was
a valid representation of an empty string...

I still think it would be a good idea to define it like that, but at
least I know it isn't the case!

[toc] | [prev] | [next] | [standalone]


#42495

FromKeith Thompson <kst-u@mib.org>
Date2014-04-02 15:03 -0700
Message-ID<ln4n2bfkyu.fsf@nuthaus.mib.org>
In reply to#42484
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> wrote:
[...]
>> Implementations of strlen are not required to detect any of these
>> errors; they all have undefined behavior.  (It would be easy to
>> detect a null pointer argument, but the overhead might be an issue,
>> and on most systems it's likely to cause a run-time fault anyway
>> -- and it's not clear what it should return for a null pointer
>> argument anyway.)
>
> I suppose 0 and -1 are not so unreasonable choices. 

Defining strlen to return 0 would encourage treating both "" and
NULL as empty strings.  If you wanted to *consistently* change the
language and library so that a null pointer always acts like an
empty string, I suppose you could, but I think it would be overly
complicated and would, on many systems, impose run-time overhead
without much benefit.

-1 would convert to SIZE_MAX, which would lead to bugs where a
program would treat a null pointer as if it pointed to a very very
long string.

In the absence of exception handling, I prefer leaving strlen(NULL)
undefined, which allows implementations to trap it, which at least
potentially can catch bugs earlier.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web