I was just playing around with the pointers and malloc
function,
I tried to create an array using malloc
and then assign It's values using a for
loop
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main () {
// Allocate enough memory for 3 integer elements
int *array = (int *) malloc(sizeof(int) * 3);
// Write data, even tho I have allocated enough memory
// for only 3 integer elements, I am able to write more!
// Somehow if I write 7 elements instead of 6, I'll get an error!
for(int i = 0; i<6; i++) {
array[i] = i*5;
}
// Read the data, everything is fine
for(int i = 0; i<6; i++) {
printf("%d. %p (%d)\n", i, &array[i], array[i]);
}
// Let the memory go...
free(array);
return 0;
}
At first, I was trying to write on memory for only 3 elements, but I "accidentally" did write 4 elements, and shockingly (for me) It worked without any error!
So I tried with more elements, I was able to write 6 elements using the pointer and the memory I was allocated for only 3 elements,
Till 6 elements, it worked, But if I write 7 elements, I get an error and the core will get dumped.
malloc.c:2379: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
I know It's wrong to write on a spot that I haven't allocated, but I just can't understand how it is working properly with 6 elements, and not with 7 elements...
I ran the code a bunch of time Here is an example of the results with 6 elements:
0. 0x55bc431fe2a0 (0)
1. 0x55bc431fe2a4 (5)
2. 0x55bc431fe2a8 (10)
3. 0x55bc431fe2ac (15)
4. 0x55bc431fe2b0 (20)
5. 0x55bc431fe2b4 (25)
The pointers are right, The values are right, If it would return me some junk value then it wasn't weird (I guess!?)
So, How am I writing 6 integers (6 * sizeof(int)
) on memory I allocated for 3 (3 * sizeof(int)
)?
And why it doesn't do the job the same way when I try to write 7 integers?
I even tried to running code using valgrind
and see if there is any useful information (I'm a newbie)
==311441== Memcheck, a memory error detector
==311441== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==311441== Using Valgrind-3.16.0.GIT and LibVEX; rerun with -h for copyright info
==311441== Command: ./6els
==311441==
==311441== Invalid write of size 4
==311441== at 0x109197: main (in /home/alireza/Projects/CPointerz/6els)
==311441== Address 0x4a3404c is 0 bytes after a block of size 12 alloc'd
==311441== at 0x483977F: malloc (vg_replace_malloc.c:307)
==311441== by 0x10916A: main (in /home/alireza/Projects/CPointerz/6els)
==311441==
0. 0x4a34040 (0)
1. 0x4a34044 (5)
2. 0x4a34048 (10)
==311441== Invalid read of size 4
==311441== at 0x1091C0: main (in /home/alireza/Projects/CPointerz/6els)
==311441== Address 0x4a3404c is 0 bytes after a block of size 12 alloc'd
==311441== at 0x483977F: malloc (vg_replace_malloc.c:307)
==311441== by 0x10916A: main (in /home/alireza/Projects/CPointerz/6els)
==311441==
3. 0x4a3404c (15)
4. 0x4a34050 (20)
5. 0x4a34054 (25)
==311441==
==311441== HEAP SUMMARY:
==311441== in use at exit: 0 bytes in 0 blocks
==311441== total heap usage: 2 allocs, 2 frees, 1,036 bytes allocated
==311441==
==311441== All heap blocks were freed -- no leaks are possible
==311441==
==311441== For lists of detected and suppressed errors, rerun with: -s
==311441== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 0 from 0)
Also, the code is compiled using GCC
with no additional compile flags.
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --with-isl --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-libunwind-exceptions --disable-werror gdc_include_dir=/usr/include/dlang/gdc
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.1.0 (GCC)