我只是在玩指针和malloc函数,
我尝试使用创建一个数组malloc,然后使用for循环分配它的值
这是我的代码:
#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;
}
起初,我试图只写 3 个元素的内存,但我“不小心”确实写了 4 个元素,令人震惊的是(对我来说)它没有任何错误!
所以我尝试了更多元素,我能够使用指针写入 6 个元素,而我只分配给 3 个元素的内存,
直到 6 个元素,它工作,但如果我写 7 个元素,我会得到一个错误,核心将被转储。
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.
我知道在我没有分配的地方写是错误的,但我就是不明白它是如何使用 6 个元素而不是 7 个元素正常工作的......
我运行了很多次代码这是一个包含 6 个元素的结果示例:
0. 0x55bc431fe2a0 (0)
1. 0x55bc431fe2a4 (5)
2. 0x55bc431fe2a8 (10)
3. 0x55bc431fe2ac (15)
4. 0x55bc431fe2b0 (20)
5. 0x55bc431fe2b4 (25)
指针是正确的,值是正确的,如果它会返回一些垃圾值,那就不奇怪了(我猜!?)
那么,我如何在6 * sizeof(int)分配给 3 ( ) 的内存上写入 6 个整数 ( 3 * sizeof(int))?
为什么当我尝试写 7 个整数时它不以同样的方式完成工作?
我什至尝试使用运行代码valgrind,看看是否有任何有用的信息(我是新手)
==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)
此外,代码是GCC在没有额外编译标志的情况下编译的。
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)