4

Well, I always think that if I call malloc function, I assign specific amount of memory, but, I've just realised that if I write:

int* a = (int*)malloc(sizeof(int) * 2);

I can assign a value to a[4] or any another index, I though that, in this case, I could only assign to a[0] or a[1]. What's the concept error I have?

Timothy Jones
  • 21,495
  • 6
  • 60
  • 90
German
  • 139
  • 6

6 Answers6

2

When you write a[4], it is the same as writing *(a + 4). Since the compiler doesn't know how much memory is allocated at the address that a points to, it will happily let you address the memory.

However, the memory located there could be anything - it could be another variable used by your program, part of the stack, or just out of the bounds of your program. Accessing outside the allocated space in this way is likely to (at best) produce a segmentation fault or (at worst) introduce a security hole by overwriting other parts of your program.

You are correct in that you can only assign to a[0] or a[1] safely, but the C compiler will let you assign outside that bounds (because it doesn't know any different).

It is not safe to do a[4] in your example.


Also, it is better not to cast the result of malloc - see this answer

Community
  • 1
  • 1
Timothy Jones
  • 21,495
  • 6
  • 60
  • 90
2

In C, there is no way to check for array overflow. You can go on write beyond the array, until you enocunter writing to an invalid address or a read-only page etc.

There are some tools available which makes you detect immediately, as an when you cross the array boundary. NJAMD is one such tool, where it makes the immediate memory location beyond array boundary as read-only.

As an when you access a read-only memory, it gives SIGSEGV. so you can detect immediately an array overflow.

vamsi
  • 1,727
  • 3
  • 22
  • 25
1

The concept error is believing C will protect you! C believes you know what you are doing. You can only really use index 0 or 1, but its not going to stop you using 4 (well, the operating system might).

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
1

The reason you can do a[4] is that C doesn't do any boundary checking. You can access a cell past the boundaries of the array and C will do it.

The problem is this is very bad practice and potentially a security hole. You should not do this as it might lead to very bad and unforeseen consequences.

twain249
  • 5,666
  • 1
  • 21
  • 26
1

Undefined behaviour is just that - undefined. It might look like it's "working", but it's not.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
1

To expand on Keith's answer: You can overwrite memory on the heap since C does no compile-time or run-time bound-checking. a[x] basically adds x * sizeof(x) to pointer "a". Pointer a points to the beginning of the malloced block.

Mario Aguilera
  • 1,146
  • 1
  • 9
  • 16