Ç - 使用strcmp分段错误? [英] C - Segmentation Fault with strcmp?

查看:305
本文介绍了Ç - 使用strcmp分段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎得到地方分割故障与STRCMP功能。
我还是很新的C,我不明白为什么它给我的错误。

  INT linear_probe(htable小时,字符*项目,诠释K){
  INT磷;
  INT步= 1;
  做{
    P =(K +步++)%H->的能力;
  }而(H->按键[P] = NULL&放大器;!&放大器;的strcmp(H->!按键[P],产品)= 0);
  回磷;
}

GDB:

 计划接收信号SIGSEGV,分割过错。
从/lib64/libc.so.6 0x0000003a8e331856在__strcmp_ssse3()(GDB)帧1
在linear_probe#1 0x0000000000400ea6在htable.c(H = 0x603010,项目= 0x7fffffffde00ksjojf,K = -1122175319):52

编辑:插入的code和htable结构

  INT htable_insert(htable小时,字符*项目){
  unsigned int类型K = htable_word_to_int(项目);
  INT P =ķ%H->的能力;  如果(NULL == H->键[P]){
    H->键[P] =(字符*)malloc的(strlen的(项目)+1);
    的strcpy(H-GT&;键[P],项目);
    H-> freqs [P] = 1;
    H-> num_keys ++;
    返回1;
  }  如果(STRCMP(H-GT&;键[P],项目)== 0){
    返回++ H-> freqs [P];
  }  如果(H-GT&; num_keys == H->能力){
    返回0;
  }  如果(H-GT&;方法== LINEAR_P)P = linear_probe(H,物品,K);
  否则P = double_hash(H,物品,K);  如果(NULL == H->键[P]){
    H->键[P] =(字符*)malloc的(strlen的(项目)+1);
    的strcpy(H-GT&;键[P],项目);
    H-> freqs [P] = 1;
    H-> num_keys ++;
    返回1;
  }否则如果(STRCMP(H-GT&;键[P],项目)== 0){
    返回++ H-> freqs [P];
  }
  返回0;
}


 结构htablerec {
      INT num_keys;
      INT能力;
      INT *统计;
      焦炭**键;
      INT * freqs;
      hashing_t方法;
    };

感谢

编辑:的valgrind 的 - 我进入随机值添加到表

  sdkgj
fgijdfh
dfkgjgg
JDF
kdjfg
== == 25643条件跳转或移动依赖于未初始化值(S)
== == 25643在0x40107E:htable_insert(htable.c:87)
== == 25643通过0x400AB7:主(main.c中:75)
== == 25643
fdkjb
kjdfg
kdfg
nfdg
lkdfg
oijfd
kjsf
VMF
kjdf
kjsfg
fjgd
fgkjfg
== == 25643尺寸为8的读无效
== == 25643在0x400E0E:linear_probe(htable.c:51)
== == 25643通过0x401095:htable_insert(htable.c:87)
== == 25643通过0x400AB7:主(main.c中:75)
== == 25643地址0x4c342a0不stack'd,malloc分配或(最近)free'd
== == 25643
== == 25643尺寸为8的读无效
== == 25643在0x400E2B:linear_probe(htable.c:51)
== == 25643通过0x401095:htable_insert(htable.c:87)
== == 25643通过0x400AB7:主(main.c中:75)
== == 25643地址0x4c342a0不stack'd,malloc分配或(最近)free'd
== == 25643
== == 25643大小为1的读无效
== == 25643在0x4A06C51:STRCMP(mc_replace_strmem.c:426)
== == 25643通过0x400E3C:linear_probe(htable.c:51)
== == 25643通过0x401095:htable_insert(htable.c:87)
== == 25643通过0x400AB7:主(main.c中:75)
== == 25643地址0x210不stack'd,malloc分配或(最近)free'd
== == 25643
== == 25643
== == 25643进程终止与信号11的默认操作(SIGSEGV)
== == 25643地址0x210没有映射区域内访问
== == 25643在0x4A06C51:STRCMP(mc_replace_strmem.c:426)
== == 25643通过0x400E3C:linear_probe(htable.c:51)
== == 25643通过0x401095:htable_insert(htable.c:87)
== == 25643通过0x400AB7:主(main.c中:75)
== == 25643如果您认为发生这种情况作为一个堆栈的结果
== == 25643溢出程序的主线程(不可能的,但
== == 25643可能的),你可以尝试增加的大小
== == 25643用 - 主 - STACKSIZE =标志主线程堆栈。
== == 25643在这个运行中所用的主线程的堆栈大小是8388608。
== == 25643
== == 25643 HEAP摘要:
== == 25643在退出,使用:1982在28字节的块
== == 25643总堆的使用情况:28 allocs,0的FreeS,1982字节分配
== == 25643
== == 25643泄漏摘要:
== == 25643失去了肯定:0字节0块
== == 25643间接丧失:0字节0块
== == 25643失去了可能:0字节0块
== == 25643尚能访问:28块1982个字节
== == 25643燮pressed:0字节0块
== == 25643与重新运行--leak检查=全看到内存泄露的细节
== == 25643
== == 25643侦测到并SUP pressed错误计数,重新运行:-v
== == 25643使用--track-起源= yes来看到未初始化值来自
== == 25643错误摘要:从4语境7错误(SUP pressed:6 6)
分段错误(核心转储)


 静态unsigned int类型htable_word_to_int(字符*字){
  unsigned int类型的结果= 0;
  而(*字!='\\ 0'){
    结果=(*字++ + 31 *结果);
  }
  返回结果;
}


解决方案

除了可能性,在价值观的 htable 可能是无效的指针(即,既不是NULL也不指向一个体面的C字符串),你有一个的严重的,如果它既不包含NULL也不你要找的字符串遇到一个无限循环的问题。

有关眼前的问题,请尝试更改code为:

 的#define FLUSH fflush(标准输出); FSYNC(的fileno(标准输出))INT linear_probe(htable小时,字符*项目,诠释K){
    INT POS = K;
    做{
        POS =(POS + 1)%H->的能力;
        的printf(====== \\ n); FLUSH;
        的printf(INPK数:%d \\ n,K); FLUSH;
        的printf(posn处数:%d \\ n,POS机); FLUSH;
        的printf(cpct数:%d \\ n,H>能力); FLUSH;
        的printf(keyp:%P \\ N,H>键[POS]); FLUSH;
        的printf(键:'%s'的\\ n,H>键[POS]); FLUSH;
        的printf(项:'%s'的\\ n,项目); FLUSH;
        的printf(====== \\ n); FLUSH;
    }而((POS!= K)
          &功放;&安培; (H-GT&;键[POS]!= NULL)
          &功放;&安培; (STRCMP(H-GT&;键[POS],项目)!= 0));
    返回POS;
}

这些调试语句应该给你一个提示,以什么地方出了错。


既然你得到:

  INPK:-2055051140
posn处:-30
cpct:113
keyp:0x100000001

在飞机坠毁前权,很明显,有人在一个虚假的值传递为 K 。在负数模运算是在C标准的定义,因此你要为 POS 负值,以及执行情况。而且,由于 H-方式> POS [-30] 将是不确定的行为,全盘皆输。

无论是发现和解决code,它的传球在假值(可能是一个未初始化的变量),或者通过改变保护功能:

  INT POS = K;

  INT POS;
如果((K&小于0)||(K&GT = H->容量))
    K = 0;
POS = K;

在你的函数的开始。其实我两者都做,但那么我pretty偏执: - )


和的基础上,还没有的其他的更新(哈希键计算,如果你生成一个 unsigned int类型,然后盲目地使用它作为一个签名 INT ,你就得到负值的一个很好的机会:

 的#include<&stdio.h中GT;诠释主要(无效){
    unsigned int类型X = 0xffff0000U;
    INT Y = X;
    的printf(%U%d个\\ N,X,Y);
    返回(0);
}

此输出:

  4294901760 -65536

我的建议是使用无符号整数,对于那些显然意味着是无符号值。

I appear to be getting a segmentation fault somewhere with the strcmp function. I'm still very new to C and I can't see why it gives me the error.

int linear_probe(htable h, char *item, int k){
  int p;
  int step = 1;
  do {
    p = (k + step++) % h->capacity;
  }while(h->keys[p] != NULL && strcmp(h->keys[p], item) != 0);
  return p;
}

gdb:

Program received signal SIGSEGV, Segmentation fault.
0x0000003a8e331856 in __strcmp_ssse3 () from /lib64/libc.so.6

(gdb) frame 1
#1  0x0000000000400ea6 in linear_probe (h=0x603010, item=0x7fffffffde00 "ksjojf", k=-1122175319) at htable.c:52

Edit: insertion code and htable struct

int htable_insert(htable h, char *item){
  unsigned int k = htable_word_to_int(item);
  int p = k % h->capacity;

  if(NULL == h->keys[p]){
    h->keys[p] = (char *)malloc(strlen(item)+1);
    strcpy(h->keys[p], item);
    h->freqs[p] = 1;
    h->num_keys++;
    return 1;
  }

  if(strcmp(h->keys[p], item) == 0){
    return ++h->freqs[p];
  }

  if(h->num_keys == h->capacity){
    return 0;
  }

  if(h->method == LINEAR_P) p = linear_probe(h, item, k);
  else p = double_hash(h, item, k);

  if(NULL == h->keys[p]){
    h->keys[p] = (char *)malloc(strlen(item)+1);
    strcpy(h->keys[p], item);
    h->freqs[p] = 1;
    h->num_keys++;
    return 1;
  }else if(strcmp(h->keys[p], item) == 0){
    return ++h->freqs[p]; 
  }
  return 0;
}


  struct htablerec{
      int num_keys;
      int capacity;
      int *stats;
      char **keys;
      int *freqs;
      hashing_t method;
    };

Thanks

Edit: valgrind - me entering random values to add to table

sdkgj
fgijdfh
dfkgjgg
jdf
kdjfg
==25643== Conditional jump or move depends on uninitialised value(s)
==25643==    at 0x40107E: htable_insert (htable.c:87)
==25643==    by 0x400AB7: main (main.c:75)
==25643== 
fdkjb
kjdfg
kdfg
nfdg
lkdfg
oijfd
kjsf
vmf
kjdf
kjsfg
fjgd
fgkjfg
==25643== Invalid read of size 8
==25643==    at 0x400E0E: linear_probe (htable.c:51)
==25643==    by 0x401095: htable_insert (htable.c:87)
==25643==    by 0x400AB7: main (main.c:75)
==25643==  Address 0x4c342a0 is not stack'd, malloc'd or (recently) free'd
==25643== 
==25643== Invalid read of size 8
==25643==    at 0x400E2B: linear_probe (htable.c:51)
==25643==    by 0x401095: htable_insert (htable.c:87)
==25643==    by 0x400AB7: main (main.c:75)
==25643==  Address 0x4c342a0 is not stack'd, malloc'd or (recently) free'd
==25643== 
==25643== Invalid read of size 1
==25643==    at 0x4A06C51: strcmp (mc_replace_strmem.c:426)
==25643==    by 0x400E3C: linear_probe (htable.c:51)
==25643==    by 0x401095: htable_insert (htable.c:87)
==25643==    by 0x400AB7: main (main.c:75)
==25643==  Address 0x210 is not stack'd, malloc'd or (recently) free'd
==25643== 
==25643== 
==25643== Process terminating with default action of signal 11 (SIGSEGV)
==25643==  Access not within mapped region at address 0x210
==25643==    at 0x4A06C51: strcmp (mc_replace_strmem.c:426)
==25643==    by 0x400E3C: linear_probe (htable.c:51)
==25643==    by 0x401095: htable_insert (htable.c:87)
==25643==    by 0x400AB7: main (main.c:75)
==25643==  If you believe this happened as a result of a stack
==25643==  overflow in your program's main thread (unlikely but
==25643==  possible), you can try to increase the size of the
==25643==  main thread stack using the --main-stacksize= flag.
==25643==  The main thread stack size used in this run was 8388608.
==25643== 
==25643== HEAP SUMMARY:
==25643==     in use at exit: 1,982 bytes in 28 blocks
==25643==   total heap usage: 28 allocs, 0 frees, 1,982 bytes allocated
==25643== 
==25643== LEAK SUMMARY:
==25643==    definitely lost: 0 bytes in 0 blocks
==25643==    indirectly lost: 0 bytes in 0 blocks
==25643==      possibly lost: 0 bytes in 0 blocks
==25643==    still reachable: 1,982 bytes in 28 blocks
==25643==         suppressed: 0 bytes in 0 blocks
==25643== Rerun with --leak-check=full to see details of leaked memory
==25643== 
==25643== For counts of detected and suppressed errors, rerun with: -v
==25643== Use --track-origins=yes to see where uninitialised values come from
==25643== ERROR SUMMARY: 7 errors from 4 contexts (suppressed: 6 from 6)
Segmentation fault (core dumped)


static unsigned int htable_word_to_int(char *word){
  unsigned int result = 0;
  while(*word != '\0'){
    result = (*word++ + 31 * result);
  }
  return result;
}

解决方案

Apart from the possibility that the values in your htable may be invalid pointers (i.e., neither NULL nor a pointer to a decent C string), you have a serious problem of encountering an infinite loop if it contains neither a NULL nor the string you're looking for.

For the immediate problem, try changing the code to:

#define FLUSH fflush (stdout); fsync (fileno (stdout))

int linear_probe (htable h, char *item, int k) {
    int pos = k;
    do {
        pos = (pos + 1) % h->capacity;
        printf ("========\n");                    FLUSH;
        printf ("inpk: %d\n",   k);               FLUSH;
        printf ("posn: %d\n",   pos);             FLUSH;
        printf ("cpct: %d\n",   h->capacity);     FLUSH;
        printf ("keyp: %p\n",   h->keys[pos]);    FLUSH;
        printf ("keys: '%s'\n", h->keys[pos]);    FLUSH;
        printf ("item: '%s'\n", item);            FLUSH;
        printf ("========\n");                    FLUSH;
    } while ((pos != k)
          && (h->keys[pos] != NULL)
          && (strcmp (h->keys[pos], item) != 0));
    return pos;
}

Those debug statements should give you an indication as to what's going wrong.


Since you're getting:

inpk: -2055051140
posn: -30
cpct: 113
keyp: 0x100000001

right before the crash, it's evident that someone is passing in a bogus value for k. The modulo operation on negative numbers is implementation defined in the C standard so you're getting a negative value for pos as well. And since h->pos[-30] is going to be undefined behaviour, all bets are off.

Either find and fix the code that's passing in that bogus value (probably an uninitialised variable) or protect your function by changing:

int pos = k;

into:

int pos;
if ((k < 0) || (k >= h->capacity))
    k = 0;
pos = k;

at the start of your function. I'd actually do both but then I'm pretty paranoid :-)


And, based on yet another update (the hash key calculation, if you generate an unsigned int and then blindly use that as a signed int, you've got a good chance of getting negative values:

#include <stdio.h>

int main (void) {
    unsigned int x = 0xffff0000U;
    int y = x;
    printf ("%u %d\n", x, y);
    return(0);
}

This outputs:

4294901760 -65536

My suggestion is to use unsigned integers for values that are clearly meant to be unsigned.

这篇关于Ç - 使用strcmp分段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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