1

consider the following C code:

#define SIZE_A // >= SIZE_B
#define SIZE_B 
#define SOME_SIZE // > SIZE_B

int main() {
    int a[SIZE_A];
    int b[SIZE_B] = {0};
    memcpy(a, b, sizeof(int)*(SOME_SIZE));
    return 0;
}

assume that SIZE_A, SIZE_B are some integers and SOME_SIZE > SIZE_B and SIZE_A>=SIZE_B. what would be the consequences if:

a. SOME_SIZE < SIZE_A
b. SOME_SIZE = SIZE_A
c. SOME_SIZE > SIZE_A

I tried to run it with some values but didn't understand if there is any constancy. Thanks

6
  • 2
    If the destination buffer is too small, you get undefined behaviour. Commented Mar 1, 2016 at 13:25
  • please notice that the destination is always big enough for the info from b (SIZE_A >= SIZE_B), the question is what happens if the number of bytes we ask to deliver are larger/smaller/equal to the destination's size Commented Mar 1, 2016 at 13:27
  • 2
    If the size of the source buffer is smaller than the size of the memcpy, you get undefined behaviour too. You are reading beyond the source buffer and whatever bytes that come after the source buffer will be copied. You may even get a crash if you are reading beyond a page limit. Commented Mar 1, 2016 at 13:28
  • @MichaelWalz are you sure about that? what if SOME_SIZE == SIZE_B? Commented Mar 1, 2016 at 13:31
  • 1
    I'm sure that with SOME_SIZE == SIZE_B and SOME_SIZE <= SIZE_A you don't get UB because in that case you don't read beyond the source buffer. See answer below. Commented Mar 1, 2016 at 13:36

3 Answers 3

8

In your case (since you are copying from and to start addresses of a and b), it must hold that SOME_SIZE <= SIZE_A AND SOME_SIZE <= SIZE_B otherwise it is undefined behaviour.

In simple terms the number of bytes you copy from source to destination, should never be more than available bytes starting from the source and destination addresses which you specify to memcpy. For example, if in your case you were to copy from middle of array b, you would have to narrow down the bound for SOME_SIZE even more - as starting from middle of b there are even fewer bytes available than SIZE_B.

Sign up to request clarification or add additional context in comments.

8 Comments

does it mean that the answer to a,b,c is undefined under the assumptions I made?
@noamgot in your case C is always UB. A and B depend, if SOME_SIZE>SIZE_B then it is UB.
what does UB stand for...?
@noamgot I advise you to get familiar with UB further, if you want to code in C
@Giorgi I know what is "undefined behaviour", just didn't know that UB stands for it...
|
2

You should only copy from a zone you have declared to a zone you have declared. That means that as soon as SOME_SIZE > SIZE_B you invoke Undefined Behaviour.

Now what could happen on common implementations:

a-b) SOME_SIZE <= SIZE_A : provided you hit no segment limit, that mean trying to read from non readable memory, you will just copy garbage to the end of a after the content of b - but if you fall in non readable memory you will get a memory violation signal.

c) SOME_SIZE > SIZE_A: in addition to the problems of reading undefined memory, you write it somewhere you do not know. Very bad things are likely to happen here:

  • you could overwrite over variables
  • you could smash return addresses in the stack
  • you could try to access non writable memory and get a memory violation signal

TL/DR: as it is essentially Undefined Behaviour, what will happen is just, hmm, undefined

Comments

-3

You are copying data from after the b variable which in this case, will be random stack contents. You won't see any constancy because it is undefined. The good news (or bad news, depending upon how you look at it) is that it does has not crashed so far. If your SOME_SIZE was HUGE then I think you could get a crash on some platforms.

4 Comments

C does neither require a stack nor does it define the term "crash".
@Olaf C doesn't define "crash", but crashes do happen and most of the time (at least on current desktop computers) local variables are on the stack.
@MichaelWalz: They are very often also in registers. Anyway, it is useless to bring in implementation specifics into this. It is UB; no use in further investigating.
C may not define the term "Crash" but crashes happen. In this case, the arrays A and B not be in registers. On my PC, I just set SIZE_A to 10000000 and SIZE_B to 100 and got a crash/core/undefined behavior

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.