Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > array terminated by a NULL character ! avoiding overflows

Reply
Thread Tools

array terminated by a NULL character ! avoiding overflows

 
 
mast2as@yahoo.com
Guest
Posts: n/a
 
      02-24-2007
Hi everyone,

I am trying to implement some specs which specify that an array of
parameter is passed to a function as a pointer to an array terminated
by a NULL chatacter. That seemed fairly easy to implement. I had a
special Malloc function that would allocated the number of needed
bytes for the objects i needed to store + 1 additional byte to save
the NULL character

/*!
* \name Malloc
* \brief Allocate memory for a primitive variable
* \param size is the size of the parameter array (number of
elements)
* \return Pointer to the first byte of allocated memory
*
* Because we can't parse an array of values without knowing its size,
we
* have to terminate this array with a special character, so we stop
accessing
* its elements when we reach it. This is a standard C technique but
also
* how the parameter list is described in the ri spec (the list is
terminated
* by the special token RI_NULL).
*
*/
template<typename T>
void * PrimitiveVariable::Malloc( size_t size )
{
printf( "allocating\n" );
void * buffer;
buffer = (void*)malloc( sizeof( T ) * size + 1 );
memset( buffer, RI_NULL, sizeof( T ) * size + 1 );
return buffer;
}

Then I would set each element of the array with the desired values.
When that is done I pass the array as void* to a function.

RtFloat *vertexArray =
(RtFloat*)PrimitiveVariable::Malloc<RtFloat>( 4 );
for ( int pt = 0; pt < 4; pt++ )
{
vertexArray[pt] = 1.0f + (float)pt / 10.0f ;
//printf( "vertexArray %f\n", vertexArray[pt] );
}

Test( (void*)vertexArray) );

where Test is the following function

void Test( float* buffer )
{
size_t pt = 0;
char *c = (char*)buffer;
for ( int pt =0; pt < sizeof( float ) * 4 + 1; pt++ )
{
if ( *( c + pt ) == RI_NULL )
printf( "RI_NULL %d ", pt );
}
}

The problem with this is approach is that some bytes of the array are
actually set to 0 depending of the value of each individual element
(for example if it is a list of integers all set to 0 all the bytes
are set to 0 which is the same as NULL). So i was hoping I could loop
over the value until I would find a NULL character that would
indicated that i had reached the end of the array, but because some
bytes of the array might be set to 0, this loop potentially stops
before it actually reaches its last stored object.

This seems to be a very common technique in C/C++ so I am sure some
one as a good solution for this problem.

Thanks a lot -mark

 
Reply With Quote
 
 
 
 
Karim
Guest
Posts: n/a
 
      02-24-2007
On Feb 23, 9:57 pm, "(E-Mail Removed)" <(E-Mail Removed)> wrote:
> Hi everyone,
>
> I am trying to implement some specs which specify that an array of
> parameter is passed to a function as a pointer to an array terminated
> by a NULL chatacter. That seemed fairly easy to implement. I had a
> special Malloc function that would allocated the number of needed
> bytes for the objects i needed to store + 1 additional byte to save
> the NULL character
>
> /*!
> * \name Malloc
> * \brief Allocate memory for a primitive variable
> * \param size is the size of the parameter array (number of
> elements)
> * \return Pointer to the first byte of allocated memory
> *
> * Because we can't parse an array of values without knowing its size,
> we
> * have to terminate this array with a special character, so we stop
> accessing
> * its elements when we reach it. This is a standard C technique but
> also
> * how the parameter list is described in the ri spec (the list is
> terminated
> * by the special token RI_NULL).
> *
> */
> template<typename T>
> void * PrimitiveVariable::Malloc( size_t size )
> {
> printf( "allocating\n" );
> void * buffer;
> buffer = (void*)malloc( sizeof( T ) * size + 1 );
> memset( buffer, RI_NULL, sizeof( T ) * size + 1 );
> return buffer;
>
> }
>
> Then I would set each element of the array with the desired values.
> When that is done I pass the array as void* to a function.
>
> RtFloat *vertexArray =
> (RtFloat*)PrimitiveVariable::Malloc<RtFloat>( 4 );
> for ( int pt = 0; pt < 4; pt++ )
> {
> vertexArray[pt] = 1.0f + (float)pt / 10.0f ;
> //printf( "vertexArray %f\n", vertexArray[pt] );
> }
>
> Test( (void*)vertexArray) );
>
> where Test is the following function
>
> void Test( float* buffer )
> {
> size_t pt = 0;
> char *c = (char*)buffer;
> for ( int pt =0; pt < sizeof( float ) * 4 + 1; pt++ )
> {
> if ( *( c + pt ) == RI_NULL )
> printf( "RI_NULL %d ", pt );
> }
>
> }
>
> The problem with this is approach is that some bytes of the array are
> actually set to 0 depending of the value of each individual element
> (for example if it is a list of integers all set to 0 all the bytes
> are set to 0 which is the same as NULL). So i was hoping I could loop
> over the value until I would find a NULL character that would
> indicated that i had reached the end of the array, but because some
> bytes of the array might be set to 0, this loop potentially stops
> before it actually reaches its last stored object.
>
> This seems to be a very common technique in C/C++ so I am sure some
> one as a good solution for this problem.
>
> Thanks a lot -mark



I am not sure I understand you correctly. The integer 0 is different
in memory from NULL

integer 0 has ascii value of 48 and NULL has ascii 0

so say you have your array filled with integers 0 and terminated with
NULL

like array [ 0 ,0 , '\0' <- NULL]

this look will break after 2 iterations

char * p = &array;

while (p)
{
p++;
}

so I think instead of filling the array with integer 0 instead of NULL.

 
Reply With Quote
 
 
 
 
mast2as@yahoo.com
Guest
Posts: n/a
 
      02-24-2007

> I am not sure I understand you correctly. The integer 0 is different
> in memory from NULL
>
> integer 0 has ascii value of 48 and NULL has ascii 0
>
> so say you have your array filled with integers 0 and terminated with
> NULL
>
> like array [ 0 ,0 , '\0' <- NULL]
>
> this look will break after 2 iterations
>
> char * p = &array;
>
> while (p)
> {
> p++;
>
> }
>
> so I think instead of filling the array with integer 0 instead of NULL.



#include <stdlib.h>
#include <stdio.h>

int main()
{
int array[3] = { 1, 2, '\0' };
char *c = (char*)array;
while( c )
{
c++;
}
return 0;
}
Karim,
Hum I tried that and it doesn't work... If I get this example to work
i might be able to explain my problem a bit better ;-(

 
Reply With Quote
 
Karim
Guest
Posts: n/a
 
      02-24-2007
On Feb 23, 10:53 pm, "(E-Mail Removed)" <(E-Mail Removed)> wrote:
> > I am not sure I understand you correctly. The integer 0 is different
> > in memory from NULL

>
> > integer 0 has ascii value of 48 and NULL has ascii 0

>
> > so say you have your array filled with integers 0 and terminated with
> > NULL

>
> > like array [ 0 ,0 , '\0' <- NULL]

>
> > this look will break after 2 iterations

>
> > char * p = &array;

>
> > while (p)
> > {
> > p++;

>
> > }

>
> > so I think instead of filling the array with integer 0 instead of NULL.

>
> #include <stdlib.h>
> #include <stdio.h>
>
> int main()
> {
> int array[3] = { 1, 2, '\0' };
> char *c = (char*)array;
> while( c )
> {
> c++;
> }
> return 0;}
>
> Karim,
> Hum I tried that and it doesn't work... If I get this example to work
> i might be able to explain my problem a bit better ;-(


in your case, actually while(*c){...} would work

while (c) would never stop because the pointer is always valid.
note that the pointer would stop after only one iteration cause your
array is of INT (32 bits) and the pointer points to a char (8 bits) so
you might want to declare the pointer as an int *

so essentially , int *c = (int*)&array;



 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-24-2007
* http://www.velocityreviews.com/forums/(E-Mail Removed):
> Hi everyone,
>
> I am trying to implement some specs which specify that an array of
> parameter is passed to a function as a pointer to an array terminated
> by a NULL chatacter. That seemed fairly easy to implement. I had a
> special Malloc function that would allocated the number of needed
> bytes for the objects i needed to store + 1 additional byte to save
> the NULL character
>
> /*!
> * \name Malloc
> * \brief Allocate memory for a primitive variable
> * \param size is the size of the parameter array (number of
> elements)
> * \return Pointer to the first byte of allocated memory
> *
> * Because we can't parse an array of values without knowing its size,
> we
> * have to terminate this array with a special character, so we stop
> accessing
> * its elements when we reach it. This is a standard C technique but
> also
> * how the parameter list is described in the ri spec (the list is
> terminated
> * by the special token RI_NULL).
> *
> */
> template<typename T>
> void * PrimitiveVariable::Malloc( size_t size )
> {
> printf( "allocating\n" );
> void * buffer;
> buffer = (void*)malloc( sizeof( T ) * size + 1 );
> memset( buffer, RI_NULL, sizeof( T ) * size + 1 );
> return buffer;
> }
>
> Then I would set each element of the array with the desired values.
> When that is done I pass the array as void* to a function.
>
> RtFloat *vertexArray =
> (RtFloat*)PrimitiveVariable::Malloc<RtFloat>( 4 );
> for ( int pt = 0; pt < 4; pt++ )
> {
> vertexArray[pt] = 1.0f + (float)pt / 10.0f ;
> //printf( "vertexArray %f\n", vertexArray[pt] );
> }
>
> Test( (void*)vertexArray) );
>
> where Test is the following function
>
> void Test( float* buffer )
> {
> size_t pt = 0;
> char *c = (char*)buffer;
> for ( int pt =0; pt < sizeof( float ) * 4 + 1; pt++ )
> {
> if ( *( c + pt ) == RI_NULL )
> printf( "RI_NULL %d ", pt );
> }
> }
>
> The problem with this is approach is that some bytes of the array are
> actually set to 0 depending of the value of each individual element
> (for example if it is a list of integers all set to 0 all the bytes
> are set to 0 which is the same as NULL). So i was hoping I could loop
> over the value until I would find a NULL character that would
> indicated that i had reached the end of the array, but because some
> bytes of the array might be set to 0, this loop potentially stops
> before it actually reaches its last stored object.
>
> This seems to be a very common technique in C/C++ so I am sure some
> one as a good solution for this problem.


Remove all casts, and let the compiler inform you of the errors.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Scott McPhillips [MVP]
Guest
Posts: n/a
 
      02-24-2007
(E-Mail Removed) wrote:
> Hi everyone,
>
> I am trying to implement some specs which specify that an array of
> parameter is passed to a function as a pointer to an array terminated
> by a NULL chatacter. That seemed fairly easy to implement. I had a
> special Malloc function that would allocated the number of needed
> bytes for the objects i needed to store + 1 additional byte to save
> the NULL character
> ...code
>
> The problem with this is approach is that some bytes of the array are
> actually set to 0 depending of the value of each individual element
> (for example if it is a list of integers all set to 0 all the bytes
> are set to 0 which is the same as NULL). So i was hoping I could loop
> over the value until I would find a NULL character that would
> indicated that i had reached the end of the array, but because some
> bytes of the array might be set to 0, this loop potentially stops
> before it actually reaches its last stored object.
>
> This seems to be a very common technique in C/C++ so I am sure some
> one as a good solution for this problem.


No, you are on the wrong track. This "fairly common technique" is
suitable only for character arrays, because there is no character with
the value 0. For binary data arrays of any type you absolutely must
keep track of the size of the array.

In C++ this capability is provided nicely by std::vector.

--
Scott McPhillips [VC++ MVP]

 
Reply With Quote
 
mast2as@yahoo.com
Guest
Posts: n/a
 
      02-24-2007

> No, you are on the wrong track. This "fairly common technique" is
> suitable only for character arrays, because there is no character with
> the value 0. For binary data arrays of any type you absolutely must
> keep track of the size of the array.
>
> In C++ this capability is provided nicely by std::vector.
>
> --
> Scott McPhillips [VC++ MVP]


Thanks Scott for your help, and that makes sense... although these
specs i am looking at they have functions like that

void function( int *something, int *somethingElse, RtToken tokens[],
RtPointer params[] )
{}
typedef void *RtPointer;
typedef const char * RtToken;

Each token in tokens describes the type & length of its argument list
(array). For example
tokens[0] might be something light "16 float Var". From that I know
that the the argument list in params[0] should be lets say 16 and they
are floats. So it's easy with this information to case params[0] and
read the 16 floats, but i am trying to put some sort of overflow
checking mechanism in place. For example if params[0] length is
actually 17 then there's too many arguments. If the array length is 15
then i am missing arguments. That's what i am trying to do... i would
like to use std::vector but i need to stick to the specs in that
case !!!???

Any other idea...

I tried this other program that Karim mentionned. I really can not get
it to work. Precisely when a byte is set to 0 it is treated as a NULL
character !?


#include <stdlib.h>
#include <stdio.h>

int main()
{
int array[4];// { 'a', 'b', 'c', '\0' };
array[0]=0;
array[1]=1;
array[2]=2;
array[3]='\0';
char *c = (char*)array;
while( *c )
{
printf( ">> %c\n", *c );
c++;
}
printf( ">> done\n" );
return 0;
}

 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-24-2007
* (E-Mail Removed):
>> No, you are on the wrong track. This "fairly common technique" is
>> suitable only for character arrays, because there is no character with
>> the value 0. For binary data arrays of any type you absolutely must
>> keep track of the size of the array.
>>
>> In C++ this capability is provided nicely by std::vector.
>>
>> --
>> Scott McPhillips [VC++ MVP]

>
> Thanks Scott for your help, and that makes sense... although these
> specs i am looking at they have functions like that
>
> void function( int *something, int *somethingElse, RtToken tokens[],
> RtPointer params[] )
> {}
> typedef void *RtPointer;
> typedef const char * RtToken;
>
> Each token in tokens describes the type & length of its argument list
> (array). For example
> tokens[0] might be something light "16 float Var". From that I know
> that the the argument list in params[0] should be lets say 16 and they
> are floats. So it's easy with this information to case params[0] and
> read the 16 floats, but i am trying to put some sort of overflow
> checking mechanism in place. For example if params[0] length is
> actually 17 then there's too many arguments. If the array length is 15
> then i am missing arguments. That's what i am trying to do... i would
> like to use std::vector but i need to stick to the specs in that
> case !!!???


It it correct that the above function is one that you have to implement?

In that case, simply implement it as is.

It's a bad, awful etc. design created by a lobotomized monkey, but if
that's what you have to implement, implement it, not something else.


> Any other idea...
>
> I tried this other program that Karim mentionned. I really can not get
> it to work. Precisely when a byte is set to 0 it is treated as a NULL
> character !?
>
>
> #include <stdlib.h>
> #include <stdio.h>
>
> int main()
> {
> int array[4];// { 'a', 'b', 'c', '\0' };
> array[0]=0;
> array[1]=1;
> array[2]=2;
> array[3]='\0';


Both array[0] and array[3] are 0.


> char *c = (char*)array;


Undefined behavior results from using this pointer.

Remove all casts.

See the errors resulting.


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
mast2as@yahoo.com
Guest
Posts: n/a
 
      02-24-2007
> Remove all casts.
>
> See the errors resulting.


Alf, I am not sure why you want me to understand by removing all
cast...
you mean ?
....
char *c = array;
....

This obviously doesn't compile...
13: error: cannot convert `int*' to `char*' in initialization

whever the specs have been desgined by a monkey, no i can not really
say that... they just have been designed about 20 years ago, that's
all

 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-24-2007
* (E-Mail Removed):
>> Remove all casts.
>>
>> See the errors resulting.

>
> Alf, I am not sure why you want me to understand by removing all
> cast...
> you mean ?
> ...
> char *c = array;
> ...
>
> This obviously doesn't compile...
> 13: error: cannot convert `int*' to `char*' in initialization


Yes, that tells you that that line of code is ungood.


> whever the specs have been desgined by a monkey, no i can not really
> say that... they just have been designed about 20 years ago, that's
> all


Ah, well, I assumed a more modern specification. Seems like it is some
Pixar stuff? If so, perhaps you can use something like <url:
http://ricpp.sourceforge.net/> instead of an old C language binding?

But the question is still: is that a function that you're /calling/, or
is it a function you're /implementing/?

Details are necessary for quality help.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
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
pointer to NULL terminated array of pointer kpamafrederic@gmail.com C Programming 8 08-31-2012 04:06 AM
transforming from a non-null terminated string into a null terminatedstring ssylee C Programming 4 08-12-2008 09:57 PM
What are the common causes to null-terminated string for not having \0 character and later buffer overflow semut C Programming 7 12-05-2006 07:57 AM
struct question: NULL terminated char* array chy1013m1@gmail.com C Programming 12 09-08-2006 01:12 AM
Re: Loading null-terminated strings from file Roedy Green Java 0 07-09-2003 08:34 PM



Advertisments