Thread: null termination: seemingly unnecessary

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    40

    null termination: seemingly unnecessary

    I am currently reading about default arguments of functions in my c++ book. As an example, it shows a program that concatenates two strings, like this:

    Code:
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    void concatenate(char *str1, char *str2, int n=0);
    
    int main()
    {
    	char str1[80] = "hello there.";
    	char str2[80] = " you are cool";
    
    	concatenate(str1, str2);
    	cout << str1 << ".";
    
    	cin.get();
    }
    
    void concatenate(char *str1, char *str2, int n)
    {
    	while(*str1) str1++;
    
    	if(!n) n = strlen(str2);
    
    	while(*str2 && n)
    	{
    		*str1 = *str2;
    		str1++;
    		str2++;
    		n--;
    	}
    	
    	*str1 = '\0';
    	
    }
    i have found that removing the final step, which adds the null-termination to the final string, has no effect on the string and it's ability to be manipulated by the program.

    why is this?

    p.s, when adding the null-termination, what's the reason for the backslash? ' \0 '


    thanks A LOT for your help

  2. #2
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    The null terminator makes sure that you do not read past the array in to no-man's land for memory. Imagine a train track. Now imagine that this train track is we'll say 100 metres long. Now let's say that after those 100 metres, the track suddenly ends at a VERY large cliff. Now, in this case, the null terminator would be the point where the train stops moving along the track. If you don't have a null terminator, the train's just gonna keep on going along its merry way and BOOM, right over the cliff.

    Now, this might not *always* happen, sometimes you'll be lucky and it'll work, but when playing with trains and cliffs, it's better to be safe and save a few lives then to carelessly toss 'em over the edge, right?

    And the \0 is what is called an "escape character"

    Just as \n will print a newline, \0 stands for the value 0, and is just the character representation of it.

    -Hope that helps
    Last edited by jverkoey; 11-08-2004 at 01:28 AM.

  3. #3
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    you're seeing the results of junk left in memory having 0 in the right place by sheer dumb luck. In some cases this will cause some major problems.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  4. #4
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    it's working in that example because you're not specifying n, so it's using the entire length of the char*, leaving the '\0' on the end. more simplistically, it's copying this:

    Code:
    Hello World\0
    and then adding a \0 on the end of it, so you're really getting:

    Code:
    Hello World\0\0
    and about that whole train thing, what they mean is that if you have a char* like this:

    Code:
    Hello World
    when you try to output it it will print:

    Code:
    Hello WorldÑ¿╛í╘¿§○Θ☼3▼`7
    or it'll crash, depending on your system and what's running where in memory...
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  5. #5
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398
    Somehow, you must know how long the actual text is. When you concatenate, you do NOT want to add the 2nd 80-character array to the end of the first 80-character array!

    You could use another variable to keep track of the length of the actual text string, but C uses the null-termination. For example, the <cstring> functions like strlen() require the null termination.

    Your while-loop stops looping when it finds the null (zero) in str1. BTW - cin.get() added the null-termination to str1 for you.
    Last edited by DougDbug; 11-08-2004 at 04:06 PM.

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Let me modify your concatenate function for you:
    Code:
    void concatenate(char *str1, char *str2, int n)
    {
    	//Find the length of str1 (strlen() requires NULL termination)
    	int str1Length = strlen(str1);
    
    	//If there is no specified number of characters to copy,
    	//then copy all characters (strlen() requires NULL termination)
    	if(n == 0)
    		n = strlen(str2);
    
    	//Copy n characters from str2 to the end of str1
    	for(int i = 0; i < n; ++i)
    		str1[str1Len + i] = str2[i];
    	
    	//Terminate the string with NULL, so it can be used again
    	//in a function like this one, without getting crashes.
    	str1[str1Len + n] = '\0';
    }
    As has been mentioned before, the reason we terminate strings with a NULL '\0' character is because it is used by many library functions, and user defined ones as well, to signal the end of a string and therefore tell the function not to keep going past the end (hence the train/cliff analogy). However, char*'s are not always null terminated, especially when dealing with raw binary data; for handling such data, we use a separate variable to tell us how long the string is, since there may very well be a 0 as part of the valid data, in which case if we used a NULL to determine the end of the string, the function would be confused and cut off the rest of the data.

    A common example, if you're interested, is memcpy() and memcmp() - those don't care whether there's a null terminator or not, as long as you specify n to be the exact amount of data that you want copied.. although it'll still crash if you specify n to be greater than the size of the array.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Registered User
    Join Date
    Jun 2004
    Posts
    40
    thanks for all the replies guys.

    hunter2: indeed! those functions worked without null-termination. very interesting.

  8. #8
    Registered User
    Join Date
    Oct 2004
    Posts
    63
    jverkoey, I really liked your explanation.
    While I understood it before (through experience gone bad ) that train example really drove things home

    Whenever I think of null at the end of an array I'll think of trains. And then I'll think of /train in World of Warcraft
    "WOO WOO chugachugachugachug WOO WOO!"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. "Virtual Printer" or "Moving Printjobs"
    By extasic in forum Windows Programming
    Replies: 12
    Last Post: 06-30-2011, 08:33 AM
  2. Global Variables
    By Taka in forum C Programming
    Replies: 34
    Last Post: 11-02-2007, 03:25 AM
  3. Compiling 3rd party code problem me too
    By siavoshkc in forum C Programming
    Replies: 1
    Last Post: 09-12-2007, 05:55 AM
  4. . . . . . . - . . . - -
    By The Brain in forum C++ Programming
    Replies: 17
    Last Post: 05-17-2005, 04:01 AM
  5. Really Need Help With My Opengl Camera!!!!
    By psychopath in forum Game Programming
    Replies: 13
    Last Post: 05-28-2004, 03:05 PM