Null terminated string in C

24,479

Solution 1

Is it absolutely necessary? No, because when you call scanf, strcpy(except for strncpy where you need to manually put zero if it exceeds the size), it copies the null terminator for you. Is it good to do it anyways? Not really, it doesn't really help the problem of bufferoverflow since those function will go over the size of the buffer anyways. Then what's the best way? use c++ with std::string.

By the way, if you access/write to string1[257], that will be out of bound since you're accessing/writing 258th element in an array of size 257. (it's 0-based index)

Solution 2

String literals like "Hello World!" are null-terminated, but char arrays are not automatically null terminated.

The general principle I've always taken is to be extra cautious and assign '\0' to the the end of the string unless that causes a performance problem. In those cases, I'm extra careful about which library functions I use.

Solution 3

A literal string like "foo\nbar" is always translated to a const char literal[] with an additional zero byte at the end. (So the constant would have 8 bytes, the first being f and the last being zero).

But you are right in forcing explicitly the last byte to 0 after a strncpy.

And as Aurelio De Rosa remarked, the last correct index is 256 for an array [257].

Solution 4

Yes, you need to do that. Not all functions put the null char for you, and strncpy, as I can read in its man page, requires to have a null byte among the first n characters of src.

Solution 5

Always be careful to allocate enough memory with strings, compare the effects of the following lines of code:

char s1[3] = "abc";
char s2[4] = "abc";
char s3[] = "abc";

All three are considered legal lines of code (http://c-faq.com/ansi/nonstrings.htmlhttp://c-faq.com/ansi/nonstrings.html), but in the first case, there isn't enough memory for the fourth null-terminated character. s1 will not behave like a normal string, but s2 and s3 will. The compiler automatically count for s3, and you get four bytes of allocated memory. If you try to write

s1[3] = '\0';

that's undefined behavior and you're writing to memory that doesn't belong to s1, and would have weird effects, maybe even disrupting malloc's backend information, making it hard to free memory.

Share:
24,479

Related videos on Youtube

Arturs Vancans
Author by

Arturs Vancans

asking. learning. doing. teaching.

Updated on July 23, 2022

Comments

  • Arturs Vancans
    Arturs Vancans almost 2 years

    I am quite anxious about strings in C. Do I need to set the last char \0 or it does it by it self? If I don't do it manually then when I try to debug code and when I access string1[257] it is not null. I am having problems with freeing allocated memory of an array of strings so I thought it was a reason.

    char string1[257], string2[257];
    scanf("%s", &string2);
    string1[257] = '\0';
    strncpy(string1, string2, 257);
    string1[257] = '\0'; /* do I need to do that? */
    
    • Aurelio De Rosa
      Aurelio De Rosa over 12 years
      Note that if you declare char[257] the index goes from 0 to 256.
  • Fred Foo
    Fred Foo over 12 years
    That's \0 (NUL), not NULL.
  • John Zwinck
    John Zwinck over 12 years
    And yet NULL, 0, and '\0' have distinct meanings. No need to conflate them just because a language designed 30 years ago allows you to.
  • Fred Foo
    Fred Foo over 12 years
    Not necessarily, NULL may be defined as ((void*)0). In any case, these are different concepts that should not be conflated.
  • Michael Price
    Michael Price over 12 years
    @larsmans - Ah, yes, NULL may be a 0 cast to a void* so it may not work.
  • John Zwinck
    John Zwinck over 12 years
    strncpy is a rather "special" function with special semantics. Usually not what people want when they're just copying strings around, unfortunately.
  • Wiz
    Wiz over 12 years
    You statement about arrays depends on how it's initialized. Consider char str[4] = "test" vs char str[] = "test".

Related