Home > Software design >  If strncat adding NUL may cause the array go out of bound
If strncat adding NUL may cause the array go out of bound

Time:07-30

I have some trouble with strncat().The book called Pointers On C says the function ,strncat(),always add a NUL in the end of the character string.To better understand it ,I do an experiment.

#include<stdio.h>
#include<string.h>
int main(void)
{
    char a[14]="mynameiszhm";
    strncat(a,"hello",3);
    printf("%s",a);
    return 0;
}

The result is mynameiszhmhel In this case the array has 14 char memory.And there were originally 11 characters in the array except for NUL.Thus when I add three more characters,all 14 characters fill up the memory of array.So when the function want to add a NUL,the NUL takes up memory outside the array.This cause the array to go out of bounds but the program above can run without any warning.Why?Will this causes something unexpected? So when we use the strncat ,should we consider the NUL,in case causes the array go out of bound? And I also notice the function strncpy don't add NUL.Why this two string function do different things about the same thing?And why the designer of C do this design?

CodePudding user response:

This cause the array to go out of bounds but the program above can run without any warning. Why?

Maybe. With strncat(a,"hello",3);, code attempted to write beyond the 14 of a[]. It might go out of bounds, it might not. It is undefined behavior (UB). Anything is allowed.


Will this causes something unexpected?

Maybe, the behavior is not defined. It might work just as you expect - whatever that is.


So when we use thestrncat ,should we consider the NUL, in case causes the array go out of bound?

Yes, the size parameter needs to account for appending a null character, else UB.


I also notice the function strncpy don't add NUL. Why this two string function do different things about the same thing? And why the designer of C do this design?

The 2 functions strncpy()/strncat() simple share similar names, not highly similar paired functionality of strcpy()/strcat().

Consider that the early 1970s, memory was far more expensive and many considerations can be traced back to a byte of memory more that an hour's wage. Uniformity of functionality/names was of lesser importance.


And there were originally 11 characters in the array except for NUL.

More like "And there were originally 11 characters in the array except for 3 NUL.". This is no partial initialization in C.

CodePudding user response:

This is not really an answer, but a counterexample.

Observe the following modification to your program:

#include<stdio.h>
#include<string.h>
int main(void)
{
    char p[]="***";
    char a[14]="mynameiszhm";
    char q[]="***";
    strncat(a,"hello",3);
    printf("%s%s%s", p, a, q);
    return 0;
}

The results of this program are dependent on where p and q are located in memory, compared to a. If they are not adjacent, the results are not so clear but if either p or q immediately comes after a, then your strncat will overwrite the first * causing one of them not to be printed anymore because that will now be a string of length 0.

So the results are dependent on memory layout, and it should be clear that the compiler can put the variables in memory in any order it likes. And they can be adjacent or not.

So the problem is that you are not keeping to your promise not to put more than 14 bytes into a. The compiler did what you asked, and the C standards guarantee behaviour as long as you keep to the promises.

And now you have a program that may or may not do what you wanted it to do.

  •  Tags:  
  • c
  • Related