Like Tree2Likes
  • 1 Post By laserlight
  • 1 Post By laserlight

Why the compiler is showing strange output for the strncpy function?

This is a discussion on Why the compiler is showing strange output for the strncpy function? within the C Programming forums, part of the General Programming Boards category; Please check the following program: Code: #include<stdio.h> #include<string.h> int main(void){ char nameB[]="Jerry"; char nameA[]="Tom"; printf("\n nameA: %s",nameA); printf("\n nameB: %s",nameB); ...

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    5

    Why the compiler is showing strange output for the strncpy function?

    Please check the following program:

    Code:
    #include<stdio.h>
    #include<string.h>
    
    
    int main(void){
        char nameB[]="Jerry";
        char nameA[]="Tom";
    
    
        printf("\n nameA: %s",nameA);
        printf("\n nameB: %s",nameB);
    
    
        strncpy(nameA,nameB,4);
    
    
        printf("\n nameA: %s",nameA);
        printf("\n nameB: %s",nameB);
        printf("\n");
        return 0;
    
    
    
    
    }
    Output is following:

    Code:
    nameA: Tom
    nameB: Jerry
    nameA: JerrJerry
    nameB: Jerry
    Any idea why this strange result is coming? I think buffer overflow is a reason for it because the string nameA contains only 3 characters but the strncpy function copied 4 characters in it.

    If it is the case, then I expect a random output from the memory/other errors but here the output for nameA is JerrJerry which suggests the first 4 characters of nameB is copied successfully and nameB is printed again. Any clue?

    The output changes when I change the order of 5th and 6th line in the same program.

    Code:
    #include<stdio.h>
    #include<string.h>
    
    
    int main(void){
        char nameA[]="Tom";
        char nameB[]="Jerry";
    
    
    
    
        printf("\n nameA: %s",nameA);
        printf("\n nameB: %s",nameB);
    
    
        strncpy(nameA,nameB,4);
    
    
        printf("\n nameA: %s",nameA);
        printf("\n nameB: %s",nameB);
        printf("\n");
        return 0;
    
    
    
    
    }
    Logically, there should be no reason for a different type of result but the following output comes:

    Code:
    nameA: Tom
    nameB: Jerry
    nameA: JerrH "
    nameB: Jerry
    Now, it looks like a random result is generated for NameA for buffer overflow. But here also, first 4 characters are copied which should not happen.

    What is the reason of strange result of case 1 & 2 and why for the same program, different output is coming? I am using Codeblock with MinGW compiler.

    Any help will be highly appreciated!
    Last edited by Ahmed Tarek; 06-10-2012 at 10:47 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,315
    nameA is an array of 4 characters. When you copy 4 characters to it, none of which is a null character, it no longer contains a null terminated string, hence you cannot properly print its contents with printf and the %s format specifier in that way.
    Ahmed Tarek likes this.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    5
    Quote Originally Posted by laserlight View Post
    nameA is an array of 4 characters. When you copy 4 characters to it, none of which is a null character, it no longer contains a null terminated string, hence you cannot properly print its contents with printf and the %s format specifier in that way.
    Lots of thanks. You almost answered my question. So, the problem doesn't lie with buffer overflow but for the absence of null character. Do you have any idea why different outputs are coming for case 1 and 2?
    Last edited by Ahmed Tarek; 06-10-2012 at 10:48 PM.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,315
    Quote Originally Posted by Ahmed Tarek
    Do you have any idea why different output is coming for case 1 and 2?
    Because your compiler happened to place the arrays in memory such that the first to be declared came after the second. So, when searching for the null character in nameA for the first case, it was only found at the end of nameB. There thus was an array out of bounds access, but it didn't cause a crash because it was still accessing memory owned by the process.
    Ahmed Tarek likes this.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Apr 2012
    Posts
    5
    Also, when I tried the following code:

    Code:
    #include<stdio.h>
    
    
    
    
    int main(void){
        char nameB[]="Jerry";
        char nameA[]="Tom";
    
    
        printf("\n nameA: %s",nameA);
        printf("\n nameB: %s",nameB);
    
    
        strncpy(nameA,nameB,5);
    
    
        printf("\n nameA: %s",nameA);
        printf("\n nameB: %s",nameB);
        printf("\n");
        return 0;
    
    
    
    
    }
    The following output is coming:

    Code:
    nameA: Tom nameB: Jerry nameA: Jerryerry nameB: yerry
    Really have no idea why the string nameB[] has changed and why I got similar result of case 1 and case 2.

    Finally .....

    For the following program:

    Code:
    #include<stdio.h>
    
    
    
    
    int main(void){
        char nameB[]="Jerry";
        char nameA[]="Tom";
    
    
        printf("\n nameA: %s",nameA);
        printf("\n nameB: %s",nameB);
    
    
        strncpy(nameA,nameB,6);
    
    
        printf("\n nameA: %s",nameA);
        printf("\n nameB: %s",nameB);
        printf("\n");
        return 0;
    
    
    
    
    }
    following output comes:

    Code:
    nameA: Tom nameB: Jerry nameA: Jerryerry nameB: y


    It seems each case is different than the others. I think C has something built in which prevents the overflow since strncpy is a library function.
    Last edited by Ahmed Tarek; 06-10-2012 at 11:10 PM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,315
    I noticed that you "liked" my post #4. Do you understand its implications?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Here's a stack picture.

    Code:
    Case 1:
    
    Before strncpy:
    
    T  <-- nameA
    o
    m
    \0
    J  <-- nameB
    e
    r
    r
    y
    \0
    
    
    After strncpy:
    
    J  <-- nameA
    e
    r
    r
    y  <-- nameB
    e
    r
    r
    y
    \0
    
    
    Case 2:
    
    Before strncpy:
    
    J  <-- nameB
    e
    r
    r
    y
    \0
    T  <-- nameA
    o
    m
    \0
    
    After strncpy:
    
    J  <-- nameB
    e
    r
    r
    y
    \0
    J  <-- nameA
    e
    r
    r
    ???
    ???
    ???
    Note that strncpy does not automatically zero-terminate a string (as strcpy would).
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  8. #8
    Registered User
    Join Date
    Apr 2012
    Posts
    5
    Quote Originally Posted by laserlight View Post
    I noticed that you "liked" my post #4. Do you understand its implications?
    I understand the following:

    Array nameA[] and nameB[] is organized in the compiler in a way so that nameB[] will be declared immediately after nameA[] will be declared. First, four characters from array nameB were copied to array nameA[] since array nameA is a array with 4 characters including the null terminator. But the modified nameA[] doesn't contain the null character and the compiler continued the operation until it found a null terminator at the end of the nameB[] and for this reason, nameb[] copied again after Jerr and finally becomes "JerrJerry" which includes a null terminator.

    Now, "JerrJerry" is a string of 10 characters including the null terminator. But it exceeds the array range/bounds of 4 characters and therefore a crash is expected. You said this crash didn't occurr because it was still accessing memory owned by the process.

    I have doubt though about what you mean by "owned by the process". I think you mean the necessary memory needed for the operation, which has no relation with array length but depended on ROM/RAM.
    Last edited by Ahmed Tarek; 06-10-2012 at 11:40 PM.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,315
    Quote Originally Posted by Ahmed Tarek
    I have doubt though what you mean by "owned by the process". I think you mean the necessary memory needed for the operation, which has no relation with array length but depended on ROM/RAM.
    Yes, it depends on what memory has been allocated to the process by the OS. There is no guarantee that the arrays will be in adjacent memory, but in this case they are, hence we can deduce for certain that there are 4+6=10 bytes of memory owned by the process.

    Quote Originally Posted by Ahmed Tarek
    I think C has something built in which prevents the overflow since strncpy is a library function.
    It doesn't, or if a particular implementation does try to be helpful, you cannot rely on it always helping at the right time. In your last case of strncpy(nameA,nameB,6), it seems that there is no overflow because the null character of "Jerry" is copied.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,308
    Technically this is a buffer overflow problem. However the overflow is not upon writing, it is upon reading instead, which occurs within printf.

    I.e. Your actions, not nul-terminating the array, cause printf to overflow the bounds of your array as it reads the string to print it.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Command Promt showing in window programming - Compiler dependent?
    By random_cpp_user in forum C++ Programming
    Replies: 3
    Last Post: 10-23-2010, 05:24 AM
  2. strange virtual function output
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 02-08-2008, 08:08 AM
  3. terminal output not showing output properly
    By stanlvw in forum C Programming
    Replies: 13
    Last Post: 11-19-2007, 10:46 PM
  4. strange compiler
    By LeonLanford in forum C Programming
    Replies: 20
    Last Post: 04-12-2007, 01:29 PM
  5. Strange function output.
    By Pickels in forum C Programming
    Replies: 3
    Last Post: 08-24-2006, 09:57 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21