Click here to Skip to main content
15,891,981 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello.I have a code in C,that I copy an array to another.
Why can I copy x array to y array?
x array has <= 30 characters and y has <= 10.
Why compiler don't hit error?

Code:

What I have tried:

C++
#include <stdio.h>

void strcpy2(char *s, char *d);

int main(void)
{   char x[30] = "abijngjnhtdjgibhbicdef";
    char y[10];
    strcpy2(x, y);
    printf("%s", y);
 }
 
 void strcpy2(char *s, char *d) 
 {   
    while (*s != '\0')
    {
        *d = *s;
        s++;
        d++;
    }
   *d = '\0';
}
Posted
Updated 26-Oct-20 2:19am

C doesn't do bound checking, it's your responsibility to ensure you're not writing outside of your array. It's one of the reasons C has better performance and it's also one of the reasons it is harder to write and debug and easier to write code that crashes.
 
Share this answer
 
Comments
Nick_is_asking 26-Oct-20 7:10am    
ooo, ok now I understand.
If I change char x[30] to char *x and char y[10] to char *y ,why compiler hit error?
Thanks.
Quote:
Why compiler don't hit error?

Because in C, you are responsible of everything. The compiler do not have to check anything.
 
Share this answer
 
Quote:
If I change char x[30] to char *x and char y[10] to char *y ,why compiler hit error?

This gets a little complicated for a beginner, but here goes ... I'll try to be gentle with you!

There are two "types" of memory that a C program uses: Heap and Stack.
Heap is a huge block of memory that is allocated to a variable when you specifically ask for it using the malloc function, and it is your responsibility to release it when you are finished using free - if you don't then you get a problem called a "memory leak" where you program just keeps grabbing more and more memory that it is no longer actually using. In extreme cases, this can cause you app or the system to crash.

Stack is a much, much smaller block of memory that is allocated to each thread (think of an app as a thread, it's not really accurate, but it'll do for the moment). And when I say "much, much smaller" I'm serious: while a Heap might use all the physical memory in your computer plus all the spare space on your hard drive ad "virtual memory", a Stack is rarely larger than 1MB. It holds all the variables that are local to a function, plus all the "return addresses" that tell your app where to "go back to" when it returns from a function. Each item (generally 32 bits of data, so an integer, or four characters) occupies one "location" on the stack, in the same way that coins in a real stack do: you add them at the top, and you can only remove them from the top as well, because trying to take them from the middle is like getting overambitious at Jenga - it all falls over! :laugh:

When you call a function, the system puts the return address on the stack and then adds enough space for all the local variables: in your case 40 bytes for the two arrays (though in practice, it'll probably allocate 32 bytes for the first on, and 12 for the second just so they start and end on a word boundary - makes it easier is all).

You then call strcpy2 and it does the same thing: stacks the return address allocates space for the two pointer parameters (though in practice those will probably now be memory at all, but use registers within the processor).
strcpy2 then copies characters from one pointer to the other - overwriting whatever was there to start with. And since this is a stack, if the destination doesn't have enough space, it doesn't notice or even care and overwrites whatever it can find - in this case the return address which is going to tell the system where to resume executing main when the function ends.
It gets to the end of the function, takes the return address you just overwrote back off the stack, and tried to execute code there - and since it's no longer a valid program location, you get an error and your app crashes.


Does that make sense? It's difficult to explain without pictures ... :laugh:
 
Share this answer
 
Comments
Nick_is_asking 26-Oct-20 8:15am    
Ok,I understand some things,because at this semester I have assembly and C.
So Ι noticed that I have to write char *y = malloc(sizeof(char) * 50) to get
50 * (1 byte) = 50 byte of memory
and then everything's alright.
OriginalGriff 26-Oct-20 8:40am    
Yes - maybe!
That allocates the memory as Heap, but it doesn't prever memory corruption if the source is larger than the destination - it just creates bugs that are much harder to track down! :laugh:

You should probably pass a "limit" parameter which specifies how many characters at most will be copied - just the same as strncpy does:

https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/rtref/strncpy.htm

That doesn't prevent the problem (the only way to do that is to allocate the "new space" in the copy method, and then you run into memory leaks later if you aren't careful) but it does reduce it to "manageable proportions".

Why are you learning C in 2020? it's a very old language now and there are generally much better ones available!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900