Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I use pointer addition instead of malloc

Tags:

c

pointers

malloc

I was wondering why I have to use malloc to dynamically create memories, while I already have pointer addition to freely manipulate the memories. So I created this code, but this code corrupts, saying that 'stack around the variable 'a' was corrupted'

Can someone explain why this code fails?

#include <stdio.h>

int main(void)
{
    int a = 1;
    int * arr1 = &a;
    *(arr1 + 1) = 2;
    printf("%d %d\n", *arr1, *(arr1+1));
}
like image 441
Dimen Avatar asked Dec 10 '25 12:12

Dimen


2 Answers

You have no idea what the implementation might be storing at &a + 1. It might be critical information needed to maintain the sanity of the operating environment. Despite having no idea what it might be used for, you modify it. So anything can happen.

Don't write to memory that doesn't belong to you!

like image 193
David Schwartz Avatar answered Dec 12 '25 04:12

David Schwartz


Just because you can perform pointer arithmetic on some arbitrary address doesn't mean you should. C gives you great flexibility to do what you want, but that also means it trusts you to do the right thing, which you are not.

What you are attempting to do is write to a memory address sizeof(int) bytes past the address of a. That memory address is not part of a, and writing to it invokes undefined behavior.

As to what is happening in your particular case, local variables are typically stored on the stack in most hosted implementations. So if you write past the bounds of a variable, you'll most likely be overwriting an adjacent variable or the return address for the function. Given that your program is crashing, you're probably doing the latter.

Here's an illustration of overwriting another variables:

#include <stdio.h>

int main(void)
{
    int before = 0;
    int a = 1;
    int after = 0;
    int * arr1 = &a;
    *(arr1 + 1) = 2;
    printf("%d %d\n", *arr1, *(arr1+1));
    printf("before=%d, after=%d\n", before, after);
}

In this example I took your example and added a variable before and after a. When I run this, I get the following output:

1 2
before=2, after=0

You can see that before is now set to 2 even though it wasn't explicitly set. This means that it appears on the stack right after a. So by writing one past a, you end up writing to before instead.

To reiterate, this is undefined behavior. The compiler may arrange variables on the stack in any order. If you were to for example add an extra printf call or compile with different optimization settings you could get different results. I recompiled the above code with -O1 and running it resulted in a core dump.

So if need a particular amount of memory and you don't have space explicitly set aside for it, you need to call malloc to get the memory you want. Then you can read and write that block freely.

like image 32
dbush Avatar answered Dec 12 '25 05:12

dbush



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!