user2649681
user2649681

Reputation: 848

realloc crashes when pointer has an offset

I have below a simplified C program that demonstrates the problem. When I try to call realloc using a pointer, it works fine, but if I try to add an offset to the pointer(i.e. to start from a later element in an array), it fails.

# include <stdio.h>
# include <stdlib.h>

struct arbNum{
    unsigned char* bytes;
    long len;
};

void trim(struct arbNum* num){
    printf("%d,%d,%d,%d\n",num->bytes,num->bytes[0],num->bytes[1],num->len);
    unsigned char* nbytes = realloc(num->bytes,num->len);
    printf("Realloc successful.\n");
    num->bytes = nbytes;
}

int main(void){
    struct arbNum p = {calloc(2,1),2};
    trim(&p);
}

As an example, this outputs:

9247152,0,0,2
Realloc successful.

But, from the above code, changing realloc(num->bytes,num->len); to realloc(num->bytes+1,num->len-1); changes the output/behavior to this:

10361264,0,0,2

And then crashes. It may be that I do not understand pointers at all, but my current understanding is that they are essentially addresses at which another value is stored. In this case, why would supplying the pointer+1 not point to the value stored in the address one higher than the pointer, or in other words, what would act as the 1st element of an array pointed to by that pointer. What I'm trying to do is copy an array pointed to by num.bytes starting at the 1st element to a new address in memory, but clearly, it's failing for some reason.

Upvotes: 4

Views: 299

Answers (1)

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

No, you can only realloc() on the actual pointer previously returned by malloc() or family.

Otherwise, it's undefined behavior

Quoting C11, chapter §7.22.3.5

If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined. [....]

So, you're not allowed to use pointer aritmatic go generate a new address, pass that to realloc() and expect to re-allocate partially, that makes no sense.

Upvotes: 9

Related Questions