【问题标题】:Seg fault when calling a function调用函数时出现段错误
【发布时间】:2012-06-30 01:31:34
【问题描述】:

我的程序在循环迭代过程中遇到了段错误。调用中间函数后,inter_value 会打印到inter_value[199][208],然后出现段错误。 为了确保它没有超出限制访问,我首先打印数组inter_value,然后数组打印没有任何问题。

这是内存不足的象征吗?数组ctinter_value是由malloc创建的,key_byte是一个静态数组。

D = 200;
K = 256;
for(j = 0; j < D; j++)
    for(i = 0; i < K; i++)
        printf("inter_value[%i][%i] = %i\n", j, i, inter_value[j][i]);

for(j = 0; j < D; j++) {
    for(i = 0; i < K; i++) {
        intermediate(ct[j][0], key_byte[i], &inter_value[j][i]);
        printf("inter_value[%i][%i] = %i\n", j, i, inter_value[j][i]);
        fflush(stdout);
    }
}
printf("rex\n");


for(j = 0; j < D; j++) {
    for(i = 0; i < K; i++) {
        hamming_dist(ct[j][0], inter_value[j][i], &h[j][i]);
    }
}

函数中间体来了

void intermediate(unsigned char ct, unsigned char key_byte, unsigned char *inter_value){
    *inter_value = getSBoxInvert(ct^key_byte);
}

编辑 1:数组声明。

//initialize different intermediate values
inter_value = (unsigned char**)malloc(D * sizeof(unsigned char*));
if(inter_value == NULL){
    fprintf(stderr, "out of memory\n");
    return 0;
}
for(i = 0; i < D; i++){
    inter_value[i] = (unsigned char *)malloc(K * sizeof(unsigned char)); // this is fix to key size
    if(inter_value[i] == NULL){
        fprintf(stderr, "out of memory\n");
        return 0;
    }
}


//ct = malloc(row * sizeof(unsigned char*));
ct = (unsigned char**)malloc(D * sizeof(unsigned char*));
if(ct == NULL){
    fprintf(stderr, "out of memory\n");
    return 0;
}
for(i = 0; i < D; i++){
    //ct[i] = malloc(column * sizeof(unsigned char));
    ct[i] = (unsigned char *)malloc(column * sizeof(unsigned char));
    if(ct[i] == NULL){
        fprintf(stderr, "out of memory\n");
        return 0;
    }
}

unsigned char key_byte[256] = {0};

编辑2:段错误之前的打印输出。

inter_value[199][233] = 214
inter_value[199][234] = 119
inter_value[199][2

编辑 3:gdb 输出(似乎指向另一个函数)

程序收到信号SIGSEGV,分段错误。 0x0804a3f5 in hamming_dist (ct=31 '\037', inter_value=203 '\313', h=0x2) at cpa.cpp:53 53 *h = c;

编辑 4:从 gdb 发出回溯命令后...

#0 0x0804a3f5 in hamming_dist (ct=31 '\037', inter_value=203 '\313', h=0x2) at cpa.cpp:53

#1 0x0804aff5 in main (argc=3, argv=0xbffff2f4) at cpa.cpp:266

编辑 5:在它之前添加 hamming_dist 函数调用和 printf 调用。

编辑 6:h 的初始化

int **h;
h = (unsigned int**)malloc(D * sizeof(unsigned int*));
if(h == NULL){
    fprintf(stderr, "out of memory\n");
    return 0;
}
for(i = 0; i < D; i++){
    h[i] = (unsigned int*)malloc(K * sizeof(unsigned int)); // this is fix to key size
    if(h[i] == NULL){
        fprintf(stderr, "out of memory\n");
        return 0;
    }
}

编辑 7:hamming_dist 函数声明。

void hamming_dist(unsigned char ct, unsigned char inter_value, int *h){
    int temp;
    temp = ct ^ inter_value;
    //then count No. of ones
    int c; // c accumulates the total bits set in v
    for (c = 0; temp; c++)
        temp &= temp - 1; // clear the least significant bit set

    *h = c;
}

【问题讨论】:

  • 打印值不足以证明您没有越界访问。 inter_value 是如何声明的?
  • 请提供一个展示问题的最小完整示例
  • 确保您的 printfs 正在刷新。看在 Ritchie 的份上,请使用调试器!
  • @JimBalter:实际上并非无害。在某些(较旧的)编译器(即实现 C89 的 VS)上,强制转换返回值可能会隐藏您忘记包含 stdlib.h 的事实,因为它会被假定返回 int.. 确实,您不应该写了一些不必要的代码,这说明做这件事的人并没有真正理解 C 是如何处理指针类型的
  • 强制转换 malloc 结果在 C 中不是一个好主意,因为它可以伪装未声明的 malloc(编译器认为返回 int

标签: c++ c segmentation-fault


【解决方案1】:

您的段错误是因为&amp;h[j][i] 在作为 hamming_dist 参数 h 的值传递时为 0x2,它试图取消引用并存储到其中。这显然是因为早期的越界存储覆盖了h[j]

请注意,在 malloced 缓冲区中越界写入可能会产生直到在您的程序中任意稍后才会出现的效果。它们可能根本不会出现......直到您发布代码并且一些客户使用恰好触发错误的输入运行它。

【讨论】:

  • 我实际上初始化了 h... 请参阅我的编辑 6。
  • 我还添加了 hamming_dist 函数定义。
  • 请停止所有这些编辑,并按顺序发布程序的相关部分。事实上,&amp;h[j][i] 在传递给 hamming_dist 时的值为 0x2,而 *h = c; 会导致 seg 错误。花更多时间找出原因,减少将 sn-ps 发布到 SO 的时间。
  • 当 h 的值为 ===> 2 Program received signal SIGSEGV, Segmentation fault. 0x0804a3f5 in hamming_dist (ct=31 '\037', inter_value=203 '\313', h=0x2) at cpa.cpp:53 ...你认为gdb在骗你吗?您是否认为它巧妙地找出了导致段错误但在您的程序中并没有真正发生的事情?事实是很清楚:h 是 2,你试图在位置 2 存储一个 int,它是 memfaults。去修吧。
  • 您的越界商店可能覆盖了 h。我的回答仍然是正确的,所以你应该接受它,尽管我付出了所有的努力。而且,如果你包含了整个程序,而不仅仅是 sn-ps,这里有人会看到那个越界存储。跨度>
猜你喜欢
  • 2011-01-08
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多