Reg: strncpy function

Hi All,
Please clear the following doubt.

int main()
{
char str1[25];
char str2[] = "HelloWorld";
int len = strlen(str2);
strncpy(str1, str2, len);
str1[len] = '\0';
printf("%s", str1);
}

In the above program i'm initializing the 10th byte of str1[10] to null.
what will happen to the memory of byte 11 to 25 of str1?.

Is that memory will be used by compiler or that memory will be kept undistrubed.

Thanks in Advance,
Arun.

The contents of the memory are undefined for str1 because you did not initialize it.
After you copy "HelloWorld" and then nul terminate, then the memory after that is still undefined, ie. probably garbage. You do realize that local variables live in the user stack... and that uninitialized varables lead to bad things like buffer overflows?

One way of several to improve the code.

Also, notice I used code tags so it is easy to read:

int main()
{
   char str1[25];
   char str2[] = "HelloWorld";
   
   memset(str1,'\0',sizeof(str1));
   strncpy(str1, str2, strlen(str2));
   printf("%s\n", str1);
   return 0;
}

memset initializes str1, and main() ALWAYS returns an integer. This is very important in UNIX. Because it was initialized, str1 does need the '\0' tacked on the end. Unless you strncpy something else in there.

You don't need to blank that whole block of memory to blank the string. All you need is

str1[0]='\0';

as jim said,

its good that the variable should be given to memset,
char array blocks should be initialized.

without memset and just with a string delimiter '\0',
you end up in possible garbage retention for the char array.

There is always the potential for garbage retention in the array. The solution is to use it intelligently.

thats very much true C688...

as an user of existing libs, i dont think so programmer gets down to the stack to prevent any crash... an actual workout with memory maps and its components

And this has what to do with my example?

Like I said, there is always the potential for garbage whenever you overwrite a string of unknown contents. Should you fill all string buffers with nulls, every time you overwrite them? That could be an awful lot of nulls.

I stayed out of this, but memcpy and strncpy don't append a trailing '\0', that' why you should consider memset()

Run this code and see if you see a trailing '\0' after "HI THERE".

#include <strings.h>
int main()
{
        char tmp[32];
        memset(tmp,'%',32);
        strncpy(tmp,"HI THERE",3);
        {
                char *p=tmp;
                int i=0;
                for(i=0;i<32;i++,p++) printf("%2d ",*p);
                printf("\n");
        }
        return 0;
}

This is what I get:

kcsdev:/home/jmcnama> cat t.c
#include <strings.h>
int main()
{
        char tmp[32];
        memset(tmp,'%',32);
        strncpy(tmp,"HI THERE",3);
        {
                char *p=tmp;
                int i=0;
                for(i=0;i<32;i++,p++) printf("%2d ",*p);
                printf("\n");
        }
        return 0;
}
kcsdev:/home/jmcnama> cc t.c
kcsdev:/home/jmcnama> a.out
72 73 32 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
kcsdev:/home/jmcnama>

ok.. lets take you dont fill them using memset..

once you prepare the string .. with strncpy, strcpy (some func)

how do u notify the string termination ?

memset and strncpy are the only standard C string "copy" functions that don't null-terminate the destination string.

And Corona's example of

str[0]='\0';

doesn't handle strncpy, it allows buffer overrun, because there is no trailing '\0'
except by luck of what happened to be in the memory allocated on the stack for str1...

strncpy(dst,src,n-1);
dst[n]='\0';

Covers all situations. If strncpy has enough space, it will leave a null terminator at or before the index n, and putting the terminator at the end will do nothing. If it does not have enough space, then by definition it will need one at index n.

This is my understanding of strncpy. As long as it copies n + m characters into the destination from a source that is n bytes long, you're okay.
n-1 and it does not null-terminate.

i feel the statements are contradictory !!! :confused: :confused: :confused:

That's exactly my point, Jim. If you're copying a string into a buffer that's too small, it won't be null terminated. If you're copying a string that's smaller than the buffer, it will be null-terminated.

So, just put a null on the end of the buffer, and it will always be null terminated no matter what the size of the input string.

As usual, there's no need to nullify the whole buffer. For small buffers you can get away with it, but it's not good to get into the habit of it.