中止,而不是明确的内存冲突段错误 [英] Abort instead of segfault with clear memory violation

查看:107
本文介绍了中止,而不是明确的内存冲突段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我跟C字符串打交道时临到这个怪异的行为。这是从K&放大器练习; R本书,我应该写追加一根弦到另一个字符串的结尾的功能。这显然​​需要目标字符串有足够的内存分配,使源字符串相符。这里是code:

  / * strcat的:在dest的末尾源的副本内容* /
 的char * strcat的(字符* DEST,为const char *源){
  字符* D = DEST;
  //移动到dest的结束
  而(* DEST!='\\ 0'){
    DEST ++;
  } // * DEST现在是'\\ 0'  而(*源!='\\ 0'){
    * DEST ++ = *源++;
  }
  * DEST ='\\ 0';
  返回D组;
}

在测试过程中我写了下面,期待一个段错误的程序运行时发生:

  INT的main(){
  S1的char [] =你好;
  S2的char [] =eheheheheheh;
  的printf(%S \\ n,strcat的(S1,S2));
}

据我了解S1得到的数组6 字符分配和S2的13阵列字符。我认为,当 strcat的尝试以高于6指标写入S1该计划将段错误。相反,一切工作正常,但程序不会完全退出,而不是它的作用:

  helloeheheheheheh
zsh中:中止./a.out

和code 134,我认为这只是意味着放弃退出。

为什么我没有得到段错误(或如果字符串在栈上分配覆盖S2)?在哪里这些字符串内存(堆栈或堆)?

感谢您的帮助。


解决方案

  

我认为当strcat的尝试以高于指标写入 S1 6 该计划将段错误。


写你已经在栈上分配的内存边界之外是不确定的行为。在段错误通常调用此未定义的行为(但不总是)的结果。 但是,你不能的确定的一个段错误会发生。

维基百科的链接解释它相当不错:


  

当未定义行为的一个实例时,只要语言规范而言什么事情都可能发生,也许什么都没有。


因此​​,在这种情况下,你可以得到一个段错误,程序可能会中止,或有时它可能只是运行正常。或者说,任何东西。没有保证结果的方式。


  

在哪里是在内存(堆栈或堆)这些字符串?


既然你已经声明他们作为的char [] 有主(),它们是数组< A HREF =htt​​p://en.wikipedia.org/wiki/C_syntax#Storage_duration_specifiers>自动存储,这对于实际用途意味着他们是在栈上。

I came upon this weird behaviour when dealing with C strings. This is an exercise from the K&R book where I was supposed to write a function that appends one string onto the end of another string. This obviously requires the destination string to have enough memory allocated so that the source string fits. Here is the code:

 /* strcat: Copies contents of source at the end of dest */
 char *strcat(char *dest, const char* source) {
  char *d = dest;
  // Move to the end of dest
  while (*dest != '\0') {
    dest++;
  } // *dest is now '\0'

  while (*source != '\0') {
    *dest++ = *source++;
  }
  *dest = '\0';
  return d;
}

During testing I wrote the following, expecting a segfault to happen while the program is running:

int main() {
  char s1[] = "hello";
  char s2[] = "eheheheheheh"; 
  printf("%s\n", strcat(s1, s2));
}

As far as I understand s1 gets an array of 6 chars allocated and s2 an array of 13 chars. I thought that when strcat tries to write to s1 at indexes higher than 6 the program would segfault. Instead everything works fine, but the program doesn't exit cleanly, instead it does:

helloeheheheheheh
zsh: abort      ./a.out

and exits with code 134, which I think just means abort.

Why am I not getting a segfault (or overwriting s2 if the strings are allocated on the stack)? Where are these strings in memory (the stack, or the heap)?

Thanks for your help.

解决方案

I thought that when strcat tries to write to s1 at indexes higher than 6 the program would segfault.

Writing outside the bounds of memory you have allocated on the stack is undefined behaviour. Invoking this undefined behaviour usually (but not always) results in a segfault. However, you can't be sure that a segfault will happen.

The wikipedia link explains it quite nicely:

When an instance of undefined behavior occurs, so far as the language specification is concerned anything could happen, maybe nothing at all.

So, in this case, you could get a segfault, the program could abort, or sometimes it could just run fine. Or, anything. There is no way of guaranteeing the result.

Where are these strings in memory (the stack, or the heap)?

Since you've declared them as char [] inside main(), they are arrays that have automatic storage, which for practical purposes means they're on the stack.

这篇关于中止,而不是明确的内存冲突段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆