1

I write my own version of strcpy(). I learn it from http://pweb.netcom.com/~tjensen/ptr/ch3x.htm .

So.. here is the source code:

#include <stdio.h>

char *my_strcpy(char *dst, char *src);
char *my_strcpy(char *dst, char *src)
{
    char *ptr = dst;
    while (*src)
    {
        *ptr++ = *src++;
    }

    *ptr = '\0';

    return dst;
}

int main(int argc, const char *argv[])
{
    char strA[] = "Awesome string! Yes it is G-String!";
    char strB[20];

    my_strcpy(strB, strA);
    puts(strB);

    return 0;
}

In function main() i experiment to change:

char strA[] = "Awesome string! Yes it is G-String!";
char strB[20];

become

char *strA = "Awesome string! Yes it is G-String!";
char *strB;

And, yay! it works! Then the question is, How char *strB and char *ptr = dst (inside my_strcpy() ) work? In my understanding, they not have more than one space in memory. They only have one space in memory since char *strB not initialized as like char *strA . Whether it can be considered as a automatic / dynamic space creation in memory? How the data stored?

Please enlightenment

Thank you :)

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 1
    `char strA[] = "Awesome string! Yes it is G-String!";` is `char[36]`. You're not stuffing that into a `char[20]` without invoking *undefined behavior*. – WhozCraig Feb 20 '15 at 06:52
  • Do you understand what `*ptr++ = *src++;` does? – alk Feb 20 '15 at 07:06
  • @alk , Yes i know what the expression does. Incrementing or seek one step next to 1 byte. Am i right? please correction. But i don't understand how it work, so... that's why my question title is: Whether it can be considered as a automatic / dynamic space creation in memory? – Oka Prinarjaya Feb 20 '15 at 07:19

5 Answers5

2

In both char strB[20]; and uninitialized char * strB, you'll face Undefined behaviour.

In the former case, you'll be writing past allocated memory.

In the later case, you'll try to access uninitialized memory.

However, as per the standard function comparison, my_strcpy() function behaviour is okay. If you want to add some preventive measure to your version of the code, consider at least adding a Check for NULL incoming pointer for both source and destination.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • which expression on my code will writing past allocated memory? `char strB[20];` or `char * strB` ? And which expression on my code will access uninitialized memory? . You are not explain to me how it work. – Oka Prinarjaya Feb 20 '15 at 06:53
  • @OkaPrinarjaya In case of `char strB[20]`, as per your source string, you have more than `20` chars, so effectively you'll write past the allocated memory of `20` chars in destination. – Sourav Ghosh Feb 20 '15 at 06:56
  • @OkaPrinarjaya, aka [Buffer overflow](http://en.wikipedia.org/wiki/Buffer_overflow), writing data past the end of allocated memory can sometimes be detected by the operating system to generate a segmentation fault error that terminates the process. – David Ranieri Feb 20 '15 at 07:00
  • @SouravGhosh, Any visual reference? to make me understand about Past Allocated Memory. I mean how memory looks like when in Past Allocated Memory condition. Thank you. – Oka Prinarjaya Feb 20 '15 at 09:37
  • @OkaPrinarjaya It is there in the above [link](https://en.wikipedia.org/wiki/Buffer_overflow#Example), no? Please let us know if you're not able to understand any specific illustration in there. – Sourav Ghosh Feb 20 '15 at 09:56
  • 'e' in ASCII equals 101 decimal. '\0' in ASCII equlas 0 decimal. 1979+101+0 = 2080. But the example say: "B's value has now been inadvertently replaced by a number formed from part of the character string. In this example "e" followed by a zero byte would become 25856." Sorry not relevant with the main topic. – Oka Prinarjaya Feb 20 '15 at 10:46
  • @SouravGhosh, Ok Sourav, now i understand what is past-allocated-memory from this sentence: `....but A can take only 8 bytes. By failing to check the length of the string, it also overwrites the value of B:` `B's value has now been inadvertently replaced by a number formed from part of the character string. In this example "e" followed by a zero byte would become 25856.` – Oka Prinarjaya Feb 20 '15 at 10:48
  • @OkaPrinarjaya yes, _replace_ is not `sum`, right? It's _overwriting_ the previous value. :-) – Sourav Ghosh Feb 20 '15 at 10:49
1

If

char *strA = "Awesome string! Yes it is G-String!";
char *strB;

works then it is undefined behvaior. strA is a string literal and is read-only. Whereas strB is just a pointer and is not pointing to any valid memory location and accessing/writing unallocated memory is undefined behvaior.

Gopi
  • 19,784
  • 4
  • 24
  • 36
1

it can be considered as a automatic / dynamic space creation in memory?

No, in none of your examples the function my_strcpy() allocates any memory for the destination "string".

alk
  • 69,737
  • 10
  • 105
  • 255
  • `*ptr++ = *src++` isn't that a space creation in memory? in my understanding, each 1 byte step, it will create 1 byte space in memory. My compiler not complaining / producing error about undefined behavior. Thank you for all peoples here give a correction to my code and introduce me about undefined behavior. And Ok.. i will accept your review is that none of my code allocates any memory for the destination – Oka Prinarjaya Feb 20 '15 at 07:53
  • @OkaPrinarjaya: "*isn't that a space creation in memory?*" No, it isn't. All it does is copy from where `src` points to where `ptr` points as many bytes as the type they are pointing to uses, and also then increases both pointers by as many bytes as the type they are pointing to uses, that is one byte, the size of a `char` in this case. – alk Feb 20 '15 at 07:58
  • aahh thank you, this answer is what i need. Ok once again, related to my experiment, `strB` is just a pointer and is not pointing to any valid memory location and accessing/writing unallocated memory is undefined behavior. if it is not a space creation, is it expanding an existing space? and why my compiler not complaining or producing segmentation fault?? – Oka Prinarjaya Feb 20 '15 at 08:11
  • @OkaPrinarjaya: "*is it expanding an existing space?*" No it isn't. "*why [is] my compiler not complaining*" it is, by "*producing segmentation fault*". – alk Feb 20 '15 at 08:30
  • aahh Ok... now it is clear for me. thank you very much! – Oka Prinarjaya Feb 20 '15 at 08:55
0

It is undefined behavior.

char *strA = "Awesome string! Yes it is G-String!";// It is stored in a read only memory.
char *strB;// it is uninitialized pointer and not pointing to any where.

In first case,

char strB[20]; 

It is also a undefined behavior. first string length greater that twenty.

Karthikeyan.R.S
  • 3,991
  • 1
  • 19
  • 31
0

I think there is a misunderstood on function prototype. Do you know why have you writing this line ?

char *my_strcpy(char *dst, char *src);

This is a function prototype, it says to the compiler:

you will see a function named my_strcpy(char *dst, char *src) but, if you see you need it (see Subroutine) before I define it don't worry, I explain later how it works.

So write a function prototype following by definition of this function is a nonsense.
You could remove the function prototype or you could keep prototype if you write this:

#include <stdio.h>

char *my_strcpy(char *dst, char *src);

int main(int argc, const char *argv[])
{
    [...]
    my_strcpy(strB, strA);
    [...]
}

char *my_strcpy(char *dst, char *src)
{
    [...]
}

Because the compiler read line by line, from the top to the bottom.
So when it will be in main() at line my_strcpy(strB, strA);, if you remove char *my_strcpy(char *dst, char *src); before main() compiler will say:

I don't kown any my_strcpy(arg1, arg2) function so I stop there.

I hope this can help you!

n3xtInc
  • 1
  • 1