0

When I tried the following code:

int *no_alloc_i;
*no_alloc_i = 3;
printf("%d\n", *no_alloc_i);

my code crashed, as expected. I believe that is because I did not allocate memory dynamically to no_alloc_i (correct me if I am wrong), because doing so makes the main function return 0 and the code works as expected:

int *alloc_i = (int*)malloc(sizeof(int));
*alloc_i = 3;
printf("%d\n", *alloc_i);

Afterwards, I tried allocating memory to alloc_i, did not allocate memory to no_alloc_i and then assigned a value to no_alloc_i:

int *alloc_i = (int*)malloc(sizeof(int));
int *no_alloc_i;
*no_alloc_i = 3;
printf("%d\n", *no_alloc_i);

The problem is that the pointer no_alloc_i that I had not allocated memory to was capable of holding a value. I do not understand how allocating memory to another variable could influence the behavior of the first variable. Thank you in advance!

3
  • 1
    Undefined Behaviour (or UB) is just that: undefined. It can crash, it can behave as you expect, it can fail to compile, it can give wrong answer, it can give correct answer, it can behave different on two successive invocations... Commented Nov 7, 2021 at 8:43
  • @pmg So it could be wrong but it just happens to be right? Commented Nov 7, 2021 at 8:44
  • 3
    It is wrong, Doing what you expect makes it more difficult to make sure it is wrong, but it is wrong nevertheless. UB is always wrong (sometimes (very very seldom!) there may be excuses for it -- not in your case though) Commented Nov 7, 2021 at 8:45

1 Answer 1

2

Undefined behavior. It cannot (and shouldn't be attempted to) be predicted and relied upon*. The thing is, you just didn't assign any value to your pointer so it was uninitialized, i.e. holding a semi-random unpredictable value. If that value happens to be an address inside a memory region that's writable, using that spot in memory will "succeed" but corrupt something else because it's not your memory. If it's an address where no writable memory is allocated, you'll crash attempting to access the memory there.

It's important to realize that not every errornous behavior or action immediately results in an exception being thrown. It can for example also just cause subtle corruption of data or other issues that may or may not cause bigger trouble later.


Think of it like this:

You just wrote your shopping list on that random piece of paper you found. There is no way of saying whether that paper was actually the next empty page in your notebook anyway or it was yesterday's newspaper, your notes for today's speech, your roommate's rare author-signed copy of Goethe's "Werther" or incidentally not paper at all but your slumbering cat's belly. The outcomes can differ wildly - from everything working as expected to you getting scratched badly by a fairly furious feline, and the effects of your actions could even manifest themselves with a time delay, such as when your roommate returns from his Karate training and realizes that you blatantly vandalized his most precious piece of family heritage. Attempting to rationalize this and analyze under what conditions you can get away with it is like thinking the issue here was the wrong choice of pen, not compatible with the squishy nature of your cat's belly without applying enough force to wake her up, instead of realizing that none of this would have happened if you had stuck to using your notepad in the first place.


*: Of course, it's possible to understand what happens technically and why, and it can be quite educational. Once you understand the low-level details of it deeply enough, you can probably predict what will happen. But if you discover that a certain scenario seems to work "reliably" despite it being undefined behavior (even if you checked the generated machine code and can statically say for sure that it will work in that binary), it's still a bad idea to rely on this discovery, because one manifestation of undefined behavior can also be that it works on a specific platform or with a specific compiler only. Essentially, the compiler has to follow the specifications exactly in every scenario that is defined by them, but is allowed to do whatever it wants (or whatever was easy to do when writing the code, such as not caring about what happens in "impossible" situations) in case of things that involve "undefined behavior".

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

5 Comments

When I am assigning a value to a memory address that is not mine, shouldn't the return value of the main function be different than 0? (I check it using the echo %ERRORLEVEL% command).
After you released the UB anything can happen. It may change the return value, it may keep 0 as the return value, it may return 0 on Wesdnesdays only... it may even return π or not return at all :-)
@BillTheKid not necessarily. You just wrote your shopping list on that random piece of paper you found. There is no way of saying whether that paper was actually the top of your notebook anyway or it was yesterday's newspaper, your roommate's rare author-signed copy of "Werther" or incidentally not paper at all but your cat's belly. The outcomes can differ wildly.
Re “It cannot (and shouldn't be attempted to) be understood”: That is false, absurdly so. When the C standard does not define the behavior of a program, its behavior nonetheless follows from the design of the compiler, the properties of the operating system, the hardware specification, and other things. It generally can be understood, and doing so is useful for improving speed and ability to diagnose bugs in programs. The knowledge is also useful to malicious actors for exploiting bugs, so understanding it also helps to counter and avoid those exploits.
@EricPostpischil OK maybe the wording isn't right. What I meant is that it shouldn't be predicted and relied upon. I edited the answer.

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.