Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我得不到';溢出错误';?_C++_C - Fatal编程技术网

C++ 为什么我得不到';溢出错误';?

C++ 为什么我得不到';溢出错误';?,c++,c,C++,C,我根据“memcpy”手册页编写了这段代码。我执行了它,但没有得到任何错误。通常,我会得到“seg fault”,因为我试图将消息复制到较小的目标 char str1[1]; char str2[] = "Big Message"; memcpy(&str1, &str2, strlen(str2)); Segfault(感谢@zneak)意味着以虚拟内存不允许的方式访问内存。在大多数情况下,这是由于试图取消对空指针的引用 在这种情况下,您会出现缓冲区溢出(这意味着未定义的行

我根据“memcpy”手册页编写了这段代码。我执行了它,但没有得到任何错误。通常,我会得到“seg fault”,因为我试图将消息复制到较小的目标

char str1[1];
char str2[] = "Big Message";

memcpy(&str1, &str2, strlen(str2));
Segfault(感谢@zneak)意味着以虚拟内存不允许的方式访问内存。在大多数情况下,这是由于试图取消对空指针的引用


在这种情况下,您会出现缓冲区溢出(这意味着未定义的行为,这意味着它可能在您的计算机上正常工作,并在另一台计算机上崩溃和烧坏)。

未定义。任何事情都有可能发生。它可能会运行、崩溃和烧毁、破坏互联网、撞车穿墙。

在C中,跨过数组边界是未定义的行为。这意味着它是非法的,但如果发生这种情况,该语言不需要特别做任何事情


换句话说,如果你有一个SEGFULT,那太棒了!这将更容易调试。但不幸的是,你不一定会得到一个。在您的情况下,您只是覆盖了相邻的内存。C没有关于数组边界的运行时信息,因此不能强制执行它们


在Linux系统上,堆栈被分配为一个大的、连续的读写(有时是可执行)内存块。除非写入的数据太多,超过了堆栈本身的边界,否则不会出现分段错误。

为什么会出现“分段错误”

“Seg故障”是指在某些平台上,当您试图访问受操作系统和/或硬件保护的地址区域时发生的故障。在您的情况下,
memcpy
没有遇到任何这样的区域


事实上,由于这种错误而出现“seg故障”是一种罕见且幸运的情况。大多数情况下,您只需悄悄地销毁位于相邻内存区域中的您自己的数据。

如果您想检查一些非法内存访问,请使用
-fsanize=address
编译它(至少需要gcc 4.8,并且必须安装libasan),然后您将收到错误报告:

==4926==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd1f1a4bf1 at pc 0x7f259efeadc4 bp 0x7ffd1f1a4bc0 sp 0x7ffd1f1a4368
WRITE of size 11 at 0x7ffd1f1a4bf1 thread T0
    #0 0x7f259efeadc3 in __asan_memcpy (/lib64/libasan.so.2+0x8cdc3)
    #1 0x4008c0 in main (/home/m/a.out+0x4008c0)
    #2 0x7f259ebbe78f in __libc_start_main (/lib64/libc.so.6+0x2078f)
    #3 0x400728 in _start (/home/m/a.out+0x400728)

Address 0x7ffd1f1a4bf1 is located in stack of thread T0 at offset 33 in frame
    #0 0x400805 in main (/home/m/a.out+0x400805)

  This frame has 2 object(s):
    [32, 33) 'str1' <== Memory access at offset 33 overflows this variable
    [96, 108) 'str2'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 __asan_memcpy
==4926==错误:地址消毒器:pc 0x7f259efeadc4 bp 0x7ffd1f1a4bc0 sp 0x7ffd1f1a4368上的地址0x7ffd1f1a4bf1堆栈缓冲区溢出
在0x7ffd1f1a4bf1螺纹T0处写入尺寸为11
#0 0x7f259efeadc3在内存中(/lib64/libasan.so.2+0x8cdc3)
#1个0x4008c0主输入(/home/m/a.out+0x4008c0)
#主管道(/lib64/libc.so.6+0x2078f)中的2个0x7f259ebbe78f
#3 0x400728输入/启动(/home/m/a.out+0x400728)
地址0x7ffd1f1a4bf1位于帧中偏移量33处的线程T0堆栈中
#0 0x400805主输入(/home/m/a.out+0x400805)
此帧有2个对象:

[32,33]“str1”见多重重复…………”通常,我应该得到“seg fault”-谁告诉你的?我知道它也是UB,不应该是
memcpy(str1,str2,strlen(str2))
?Segfault意味着以虚拟内存不允许的方式访问内存。它不一定取消对空指针的引用。它可能是取消对未映射地址的引用、写入只读位置或执行不可执行的位置。若编译器检测到未定义的行为,则要了解未定义的行为意味着什么。为什么会这样做生成可执行文件而不生成编译错误?编译器不需要在使用未定义的行为时抛出错误。请参阅:因为这就是UB的意思。具有有效语法的可编译代码将烧掉您周围的一切。“C没有关于数组边界的运行时信息,因此无法强制执行它们。”更像“C没有指定运行时数组边界”,给定的实现可以强制执行它们。