tags:

views:

114

answers:

3

Hello,

gcc 4.4.4 c89

I was just experimenting with a int array. And something just came to my mind. Can I nul terminate it. For example, I am using a 0 to nul terminate. However, 0 could well be a valid value in this array.

The code below will terminate after the 5. Even though I mean 0 to be a valid number. However, I could specify the size of the array. But in this case, I don't want to this as I am just interested in this particular problem.

Many thanks for any advice,

#include <stdio.h>

static void test(int *p);

int main(void)
{
    int arr[] = {30, 450, 14, 5, 0, 10, '\0'};

    test(arr);

    return 0;
}

static void test(int *p)
{
    while(*p) {
        printf("Array values [ %d ]\n", *p++);
    }
}
+10  A: 

In short, no. Technically nul characters are equally valid in strings too, it's just a convention that we use them for marking the end of a string, and all the standard library functions expect that. There are "double nul-terminated" strings that end in \0\0 for cases where a string needs to contain a \0, but then of course you have the problem of not being able to store \0\0 in the string.

If you don't want to store an array's size separately (or use trickery like sizeof), you need to come up with a sentinel that can be stored in that type but you know won't be part of the array; you could use 45 as long as you're sure arr won't have that as a valid value, it just needs to be unique

Michael Mrozek
How do you know that your chosen magic number will still be a valid magic number later? You could use the maximum value for an integer as your sentinel value; that's a good convention in C# or Java. But do you know that that can always be a good sentinel value?
David
@David: There is no always-good sentinel value, and sometimes there is no good sentinel value for a given location.
David Thornley
If using a sentinel is not an option you will have to store the count of bytes in a separate variable (this is common practice, too).
0xA3
+3  A: 

In order to use a sentinel value, obviously you have to find a value that is not otherwise valid data. That is one of the drawbacks of using a sentinel (the other being the linear search required to find the length). How does something like 0xFFFF work for you?

If this were C++, I'd suggest making a class with an associated length member (or better yet, just using std::vector). For C you should probably just keep the separate length variable yourself. You can get fancy and put it and the array together in a struct if you like.

T.E.D.
+1  A: 

Simply put, \0 is the same as 0, so if you have a zero in your array your code will mistake that for the array's end:

int arr[] = {30, 450, 14, 5, 0, 10, '\0'};
                             ^ this is the end of the array

Edit: note that by "end of the array" I mean the conceptual end of the array as defined by your algorithm, rather than the actual extents of the data laid out in memory by the C programming language.

Parappa