我只是在玩指针和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)
指针是正确的,值是正确的,如果它将返回我一些垃圾值,那么它并不奇怪(我猜!!)
那么,如何在分配给3(6 * sizeof(int)
)的内存中写入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)