strncat copies junk values ....

  • Thread starter Vaddina Prakash Rao
  • Start date
V

Vaddina Prakash Rao

Good morning everyone,
Can someone comment what is wrong with these statements ..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char *final, *s="abcdefghij";
int count = 9;
final = (char *) malloc (count * sizeof(char));
strncat(final, s, count);
printf ("\nFinal = %s\n", final);
}

Why does it print some junk values ...

Thank you ..
 
M

Martin Ambuhl

Vaddina said:
Good morning everyone,
Can someone comment what is wrong with these statements ..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char *final, *s="abcdefghij";
int count = 9;
final = (char *) malloc (count * sizeof(char));
strncat(final, s, count);
printf ("\nFinal = %s\n", final);
}

Why does it print some junk values ...

Because you
1) failed to initialize *final
2) overflowed the bounds of *final

Compare to the following version of your code. Carefully consider why
each change was made:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
char *final, *s = "abcdefghij";
int count = 9;
/* note the count+1 below. */
if (!(final = malloc(count + 1))) {
fprintf(stderr, "malloc failed. Quitting.\n");
exit(EXIT_FAILURE);
}
*final = 0; /* note */
strncat(final, s, count);
printf("\nFinal = %s\n", final);
free(final); /* note */
return 0;
}
 
C

Christopher Benson-Manica

Vaddina Prakash Rao <[email protected]> spoke thus:

In addition to Martin's revisions:
char *final, *s="abcdefghij";

You may wish to change the declaration of s to

const char *s="abcdefghij";

since string literals may not be modified.
 
B

Barry Schwarz

Good morning everyone,
Can someone comment what is wrong with these statements ..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char *final, *s="abcdefghij";
int count = 9;
final = (char *) malloc (count * sizeof(char));

You don't need the cast and in fact having there serves only to force
the compiler to suppress a warning which you would want to see if you
forgot to include stdlib.h.
strncat(final, s, count);

At this point, final does not point to a string but only to an array
of char. There is no terminating '/0' in the array pointed to by
final.
printf ("\nFinal = %s\n", final);

Since final does not point to a string, you have invoked undefined
behavior by trying to print what it points to with %s.
}

Why does it print some junk values ...

Thank you ..



<<Remove the del for email>>
 
J

Jack Klein

Vaddina Prakash Rao <[email protected]> spoke thus:

In addition to Martin's revisions:


You may wish to change the declaration of s to

const char *s="abcdefghij";

since string literals may not be modified.

Hogwash. While attempting to modify a string literal in C produces
undefined behavior, the type of the string literal is "array of char"
and specifically not "array of const char".

There were several very real defects in the OP's sample code, which
Martin addressed.
 
C

Christopher Benson-Manica

Jack Klein said:
Hogwash. While attempting to modify a string literal in C produces
undefined behavior, the type of the string literal is "array of char"
and specifically not "array of const char".

Isn't having the compiler diagnose attempts to modify string literals
generally helpful?
There were several very real defects in the OP's sample code, which
Martin addressed.

Yes.
 
S

Stan Milam

Vaddina said:
Good morning everyone,
Can someone comment what is wrong with these statements ..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char *final, *s="abcdefghij";
int count = 9;
final = (char *) malloc (count * sizeof(char));
strncat(final, s, count);
printf ("\nFinal = %s\n", final);
}

Why does it print some junk values ...

Thank you ..

I've read through this thread and there are a lot of good comments. The
one obvious thing I noticed no one mentioned is a behavior of strncat().
strncat() will cease copying a string when:

1. It encounters '\0' in the source string.
2. Or count number of characters have been copied.

It is important to note in the second case strncpy WILL NOT tack on the
terminating '\0'. When this happens and an attempt is made to display
the string there can be some pretty interesting results. When the
second case happens it is up to the programmer to make sure the string
is properly terminated with '\0'.
 
C

Chris Torek

I've read through this thread and there are a lot of good comments. The
one obvious thing I noticed no one mentioned is a behavior of strncat().
strncat() will cease copying a string when:

1. It encounters '\0' in the source string.
2. Or count number of characters have been copied.

It is important to note in the second case strncpy WILL NOT tack on the
terminating '\0'. ...

You are mixing up the strncpy() and strncat() functions here.

You *did* say that sometimes "strncpy WILL NOT" include the '\0',
and this is correct; but the function in question is strncat(),
which always includes the terminating '\0'.

The strncat() function is commonly used incorrectly; this was at
least part of the reason someone invented strlcat() (along with
strlcpy()) for the various BSDs. Unfortunately (in my opinion),
neither one made it into C99.
 
S

Stan Milam

Chris said:
You are mixing up the strncpy() and strncat() functions here.

You *did* say that sometimes "strncpy WILL NOT" include the '\0',
and this is correct; but the function in question is strncat(),
which always includes the terminating '\0'.

The strncat() function is commonly used incorrectly; this was at
least part of the reason someone invented strlcat() (along with
strlcpy()) for the various BSDs. Unfortunately (in my opinion),
neither one made it into C99.

Mea Culpa! I stand corrected. Note to self: do not ever write to CLC
before I've had time to wake up and have coffee!

I've never heard of strlcat() and strlcpy. What was their purpose?
 
C

Chris Torek

I've never heard of strlcat() and strlcpy. What was their purpose?

Perhaps I should just quote from the manual page (since no one else
has responded yet):

The strlcpy() and strlcat() functions copy and concatenate
strings respectively. They are designed to be safer, more
consistent, and less error prone replacements for strncpy(3)
and strncat(3). Unlike those functions, strlcpy() and strlcat()
take the full size of the buffer (not just the length) and
guarantee to NUL-terminate the result (as long as size is
larger than 0 or, in the case of strlcat(), as long as there
is at least one byte free in dst). Note that you should include
a byte for the NUL in size. Also note that strlcpy() and
strlcat() only operate on true ``C'' strings. This means that
for strlcpy() src must be NUL-terminated and for strlcat()
both src and dst must be NUL-terminated.

Their use is similar to that of strncpy() and strncat(), except
that strncat() takes a length instead of a buffer size.

Of course, these are not Standard C functions (having not been
adopted by the C99 folks). They may just have been too late --
the first implementations appeared in OpenBSD 2.4, around late
1998 or early 1999.
 
S

sachin_mzn

For me it prints the correct value. abcdefghi
I am using HPUX c89 compiler.
Why we need to initialize memory?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top