从gcc 4.2迁移到4.8时生成seg错误的代码

时间:2016-04-26 23:25:49

标签: c gcc

在将系统从一台服务器迁移到另一台服务器后,我有一些崩溃的c代码。它在gcc 4.2.1下编译时有效,但在4.8下它崩溃了......这是代码:

void initcap(char *inbuf) {
/* freshen case in string, capitalize first letters */

  char *ptr;

  *ptr=toupper(*inbuf); /* first letter must be cap causing SEG fault */
  for (ptr=inbuf+1; *ptr; ptr++) {
    if ( (isspace(*(ptr-1))) || (ispunct(*(ptr-1))) || (isdigit(*(ptr-1))) )
      *ptr=toupper(*ptr);
    else
      *ptr=tolower(*ptr);
  }
}

导致seg错误的行是:* ptr = toupper(* inbuf);

有人可以解释我的环境中发生了哪些变化可能会使它在一个系统上运行正常,而不是在更现代的服务器上运行?什么是解决方案?我应该在代码的其他区域搜索类似的问题吗?

3 个答案:

答案 0 :(得分:3)

char *ptr;

*ptr=toupper(*inbuf); /* first letter must be cap causing SEG fault */

流行测验时间:ptr指向的是什么?

如果你已经回答了" nuthin",你就赢了!它没有初始化,因此它的初始内容是随机垃圾。恭喜您在进程地址空间中加扰了一个随机指向的字节。您已经赢得了完全随机的段错误和崩溃。

答案 1 :(得分:1)

此行不正确:

*ptr=toupper(*inbuf);

将其更改为:

*inbuf=toupper(*inbuf)

我认为这段代码从来没有正常工作过。第一个字符从未正确转换为大写。

实际发生的事情是你写了一行中的半随机内存地址,破坏了某处的内存,因为ptr在那时没有被初始化。在旧的编译器版本中,它碰巧有一个指向现有(但仍可能是不需要的)内存位置的值,因此它没有崩溃。现在看来已经发生了变化,这就是为什么你现在看到它崩溃的原因。

顺便说一下,你可能还想在它上面添加if(!*inbuf) return;,否则当给出一个空字符串时,该函数会出错。

答案 2 :(得分:0)

你有未定义的行为

char *ptr;
*ptr=toupper(*inbuf);

因为ptr未初始化。目的是大写第一个字符,所以它应该是:

*inbuf = toupper(*inbuf);

请启用所有编译器警告以捕获此类错误。