我如何在未分配的内存上写东西?

时间:2020-06-10 22:45:36

标签: c arrays memory malloc

我只是在玩指针和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) 

0 个答案:

没有答案