-1

I am trying to implement my own version of strncpy(), i found a source code from this link.

But I encountered a Unhandled exception at 0x00411ad5 in exercise 2.exe: 0xC0000005: Access violation writing location 0x00417800. everytime the code reaches this code while((x++ < n) && (*dest++ = *source++));

Here is the complete code:

char *strncpy(char * destination, const char * source, size_t n){
        char *dest;
        dest = destination;

        size_t x=0;
        while((x++ < n) && (*dest++  = *source++)); //this is where unhandled exception occurs
        while(x++ < n){
            *dest++ = 0;
        }

        return dest;
    }

int main(){
    char *sample = "blue";
    char * sample2 = "red";

    cout << strncpy(sample, sample2, 5);
    getch();
    return 0;
}

Please tell me why this occurs and how should I fix it? Thanks!

Community
  • 1
  • 1
chrisjohn016
  • 75
  • 2
  • 10

4 Answers4

2

You cannot write to a string constant (sample); write to a char array instead:

int main(){
    char *sample = "blue";
    char buffer[5];

    cout << strncpy(buffer, sample, sizeof(buffer));
    getch();
    return 0;
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
2

Your destination is "blue" which is a string literal, that is a constant. As such it is located in a read-only part of memory (and pointed at by local sample variable), thus error when writing.

Try this:

int main(){
    char sample[] = "blue";
    char * sample2 = "red";

    cout << strncpy(sample, sample2, 5);
    getch();
    return 0;
}

which makes sample an array in local, writeable memory.

CiaPan
  • 9,381
  • 2
  • 21
  • 35
  • thanks, the exception is solved. but the output is something weird. it didn't copy what is inside sample2, it gives out weird symbols. -> SOLVED, had mistaken in the return, should've returned the destination instead of the pointer. – chrisjohn016 May 14 '15 at 08:33
2

First, it was already explained to you that you can't overwrite a string that is defined like that.
Second, you cant use cout << strncpy if that function returns pointer to the end of the copied string.

Sergi0
  • 1,084
  • 14
  • 28
  • *"cant use `cout << strncpy` if that function returns pointer to the end of the copied string"* - but it doesn't - it returns a pointer to the start of the destination buffer, see [here](http://en.cppreference.com/w/cpp/string/byte/strncpy). – Tony Delroy May 14 '15 at 08:46
  • do you realize we talk about the code from the question? and that code returns dest that was incremented, not destination – Sergi0 May 14 '15 at 09:05
  • True that the question's code does do that now, but given the aim to code *"my own version of strncpy()"* - until it returns `dest` it's still buggy, and once it's fixed to return `dest` `cout` will start working. Good insight though that there's that extra bug in the existing implementation. – Tony Delroy May 14 '15 at 09:19
1

There are two main problems with your program The first one is that function strncpy has to return destination instead of dest

char *strncpy(char * destination, const char * source, size_t n){
        char *dest;
        dest = destination;

        size_t x=0;
        while((x++ < n) && (*dest++  = *source++)); //this is where unhandled exception occurs
        while(x++ < n){
            *dest++ = 0;
        }

//        return dest;
        return destination;
    }

The second one is that string literals are immutable. Any attempt to modify a string literal results in undefined behaviour.

Thus main function should be rewritten the following way

int main(){
    char sample[] = "blue";
    char * sample2 = "red";

    cout << strncpy(sample, sample2, sizeof( sample ) );

    getch();

    return 0;
}

Also it is a bad style of programming to use variable with name x as a count. It is better to use for example i.

I would write the function simpler

char * strncpy( char *destination, const char *source, size_t n )
{
        char *dest = destination;

        while ( n-- && ( *dest++  = *source++ ) );
        while ( n-- ) *dest++ = '\0';

        return destination;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335