C 为什么会发生缓冲区溢出? #包括 无效ft\u rev\u int\u选项卡(int*选项卡,int大小) { int*rev_选项卡; int*ptab; ptab=tab; 版次=制表符+尺寸; while(rev_tab!=ptab) { *rev_tab--=*tab++; printf(“%d\n”,*rev\u选项卡); } printf(“%d”,*rev_选项卡); } int main() {int数组[10]={0,1,2,3,4,5,6,7,8,9}; ft_rev_int_tab(数组,10); 返回0; }

C 为什么会发生缓冲区溢出? #包括 无效ft\u rev\u int\u选项卡(int*选项卡,int大小) { int*rev_选项卡; int*ptab; ptab=tab; 版次=制表符+尺寸; while(rev_tab!=ptab) { *rev_tab--=*tab++; printf(“%d\n”,*rev\u选项卡); } printf(“%d”,*rev_选项卡); } int main() {int数组[10]={0,1,2,3,4,5,6,7,8,9}; ft_rev_int_tab(数组,10); 返回0; },c,pointers,C,Pointers,我创建了一个反转给定整数数组的函数 但是他们显示了这个错误。如果我在linux上命令./a.out | cat-e, 他们显示 如果我命令的话。/a.它们会显示出来 为什么linux显示出使用cat-e和不使用cat-e的区别? 如果我把数组的大小设为奇数,就不会有错误! 为什么会发生这种情况?修复内存损坏 错误消息表示您的程序因中止信号而崩溃。这可能是内存损坏的结果。内存损坏往往会导致未定义的行为。因此,如果您的程序内存损坏,那么您的程序有时会崩溃,有时工作正常。你的例子就是这样。您的问题

我创建了一个反转给定整数数组的函数
但是他们显示了这个错误。如果我在linux上命令./a.out | cat-e, 他们显示

如果我命令的话。/a.它们会显示出来

为什么linux显示出使用cat-e和不使用cat-e的区别? 如果我把数组的大小设为奇数,就不会有错误! 为什么会发生这种情况?

修复内存损坏 错误消息表示您的程序因中止信号而崩溃。这可能是内存损坏的结果。内存损坏往往会导致未定义的行为。因此,如果您的程序内存损坏,那么您的程序有时会崩溃,有时工作正常。你的例子就是这样。您的问题与
cat-e
无关,只有运气好,当您在没有
cat-e
的情况下调用它时,您的程序才能正常工作。如果再运行几次程序,最终会看到另一次崩溃

在您的程序中,以下行导致内存损坏:

 #include <stdio.h>
 void    ft_rev_int_tab(int *tab, int size)
 {
  int *rev_tab;
  int *ptab;
  ptab = tab;
  rev_tab = tab + size ;
  while (rev_tab != ptab)
  {
     *rev_tab-- = *tab++;
     printf("%d\n",*rev_tab);
  }
  printf("%d", *rev_tab);
}
int main()
{  int array[10] = {0,1,2,3,4,5,6,7,8,9};
   ft_rev_int_tab(array, 10);
   return 0;
}
表达式
rev_选项卡--
是一个。修复后减量将变量减少1,并返回旧值。因此,例如,如果
rev_tab
是指向内存位置
100000
的指针,您可以运行以下行:

     *rev_tab-- = *tab++;
然后在该行之后,
rev_tab
99999
,但是
result
收到了旧值
100000

因此,在您的程序中,
rev_tab
最初指向
rev_tab=tab+size
,这是紧跟在表之后的内存位置(即,表中的最后一个内存位置是
tab+size-1
。同样,
ptab=tab;
使
ptab
指向表中的第一个内存位置。因此,当您执行
*revu tab-->=*tab++;
时,即使
revu tab--
revu tab
减少1,也意味着它现在指向最后一个内存在表中的位置,表达式
rev_tab--
的计算结果为
rev_tab
的上一个值,因此
*rev_tab--
将取消引用指向表后面的内存位置的指针。然后将
*tab++
的结果写入该内存位置。这是一个缓冲区溢出,其结果是在未定义的行为中,由于进程的任意内存可能被覆盖,导致内存损坏。程序可能会崩溃,也可能不会崩溃,这取决于损坏的严重程度

因此,要解决此问题,您应该使用:

这将修复内存损坏,避免崩溃

我建议您在调试期间启用以检测此类内存问题。如果您使用GCC或Clang,您可以通过使用
-fsanize=Address
编译来启用地址清理,这将在应用于原始程序时为您提供以下输出:

     *--rev_tab = *tab++;
其他问题
在您的问题中,您声明要反转输入数组。但是,您发布的代码无法完成此任务。您有两个指针,一个指向数组的前面,一个指向数组的后面。然后循环,递增前指针,递减后指针,直到后指针到达第一个元素在迭代的每一步中,您都会将前指针引用的值写入后指针。但是,您不会将后指针引用的值写入前指针。因此,当遍历数组的后半部分时,它会被前半部分的值覆盖,但会被lat中的值覆盖上半部分没有写入上半部分,因此它们丢失。然后继续遍历上半部分,将写入下半部分的值写入上半部分。因此,当输入数组包含
0,1,2,3,4,5
时,结果将是
0,1,2,2,1,0
。这不是您想要的结果。

请删除zs>h标记。您的问题与zsh无关。谢谢您的帮助。我了解如何使用C处理内存,我还感谢您了解新的调试器!行不是应该吗,但后半部分的值没有写入后半部分,因此它们丢失了。更改为,但后半部分的值没有写入上半场,他们输了。?@user13145713你是对的,谢谢你指出我的错误。我现在已经更正了我的答案。
     *--rev_tab = *tab++;
$ gcc -fsanitize=address -g test.c
$ ./a.out 
=================================================================
==4848==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe3396f688 at pc 0x562ef80e528a bp 0x7ffe3396f5e0 sp 0x7ffe3396f5d0
WRITE of size 4 at 0x7ffe3396f688 thread T0
    #0 0x562ef80e5289 in ft_rev_int_tab test.c:10
    #1 0x562ef80e5659 in main test.c:17
    #2 0x7f6dbecf8b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
    #3 0x562ef80e50fd in _start (a.out+0x10fd)