-4
#include <stdio.h>
#include <string.h>

char lists[10][25];
char name[10];

void main()
{
    scanf("%s" , lists[0]);
    memcpy(name , lists[0], 25);

    printf("%s\n" , name);
}

In the above code I am predefining the size of character array "name" as 10. Now when I gave the input as :

Input - abcdefghijklmnopqrstuvwxy

The output I got was the same string : abcdefghijklmnopqrstuvwxy

Should'nt I get the output as : abcdefghij ???

how this is becoming possible even though the size of array is limited to 10?

Jamzy
  • 31
  • 6
  • 3
    This is an example of *undefined behavior* which means anything may happen. Including the program working as it should. – klutt Oct 28 '17 at 17:47
  • 1
    Your code is coloring outside of the lines, very basic UB. If you want it to blow up and reformat the disk then you need more colors. Swapping the two variable declarations is worth a try. – Hans Passant Oct 28 '17 at 17:48
  • 1
    Most languages prevent you, the programmer, from writing past the end of an array. C does not. It's your responsibility to guard against this. – jarmod Oct 28 '17 at 17:52
  • You might get segmentation fault in memcpy since your copy is going out of bounds – Varun Oct 28 '17 at 17:53

2 Answers2

1

Because it doesn't know the size of the allocated memory it's writing into, and you got away with where the extra data got written. You might not on another platform, or using a different compiler, or different optimisation settings.

When passing the size parameter to memcpy (), it's a good idea to take the size of the destination memory into account.

When using char arrays, if you want to be safer about not overrunning memory, you can use strncpy (). It'll take care of inserting the trailing NULL in the right place.

Steve
  • 1,747
  • 10
  • 18
  • So you mean to say that if the block of memory available to me was 10 then this would'nt have happened ? – Jamzy Oct 28 '17 at 17:48
  • 1
    No, if the memory were 25 then you'd have no problems. C does depend on the programmer being careful about memory allocations and writing, etc – Steve Oct 28 '17 at 17:52
  • I meant to say that the available physical memory was only 10 then I would not be able to find some extra memory and then it would have raised an error or something ! Right ?? – Jamzy Oct 28 '17 at 17:56
  • Yes you might get segmentation fault if you are copying out of bounds – Varun Oct 28 '17 at 18:05
  • 1
    No, again, because `memcpy` has no knowledge about where it's copying and can't protect you. If you only have 10 bytes, pass 10 in as the size and it will make sure it only copies 10 bytes. But then your string won't be correctly NULL-terminated, so you'll have other problems. – Steve Oct 28 '17 at 18:06
0

To start with, arrays are pointers. In C there are no length checks like on Java for example.

When you write char a[2]; the OS gives you space on the memory for 2 chars. For example, let the memory be

|1|2|3|4|5|6|7|8|9|10|11|12|
 a

a is a pointer to the address 1. The a[0] = 0; is equal with *(a+0) = 0, meaning write 0 to the address a + offset 0.

So if you try to write to an address that you have not allocated, unexpected things can happen.

For example, lets say we have char a[2];char b[2]; and the memory map is

|1|2|3|4|5|6|7|8|9|10|11|12|
 a   b

Then the a[2] = 0 is equal to b[0] = 0. But if this address is an address of an other program, then a segmentation error will be raised.

Try the program (it may work with no optimizations of the compiler):

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

char a[4];
char b[4];

void main()
{
    scanf("%s" , a);    // input "12345678"
    printf("%s\n" , b); // print     "5678"
}

memcpy just copies from an address to the other the size of data you said.

In your example, you were luky because all the addresses you accessed where assigned to your program (inside your's memory page).

In C/C++ you are responsible to handle the memory correctly. Also, keep in mind that strings end at the char \0 so inside an array char str[10]; we usually have tops 9 chars and the \0.

GramThanos
  • 3,572
  • 1
  • 22
  • 34
  • 1
    I think you have a typo here: "The a[0] = 0; is equal with *(a+1) = 0, meaning write 0 to the address a + offset 0." – MFisherKDX Oct 28 '17 at 18:05
  • Yes, of course. Thank you. (It's now correct) – GramThanos Oct 28 '17 at 18:07
  • "|1|2|3|4|5|6|7|8|9|10|11|12| a b Then the a[2] = 0 is equal to b[0] = 0." If you're relying on this behavior you're in for a world of hurt. There's no telling what the compiler / optimizer might do. – MFisherKDX Oct 28 '17 at 18:10
  • In the first example, this is the hypothesis. On the code, hopefully the compiler will assign the variables sequentially. In any way as I mentioned "if you try to write to an address that you have not allocated, unexpected things can happen", `a[2]` is such an address. – GramThanos Oct 28 '17 at 18:14
  • Got it. I first thought you were implying the allocation would *necessarily* be laid out in that sequential manner. I see you are saying *assuming the variables are* laid out in this manner .... then the behavior would be as follows .... – MFisherKDX Oct 28 '17 at 18:37