C中程序结束时的分段错误

时间:2016-08-09 10:00:54

标签: c segmentation-fault gdb valgrind

执行完所有操作后发生分段错误。我试了几个小时但仍然无法找到问题。我感到沮丧,感谢任何帮助!

所有代码都在目录" KNN - GitHub"在此链接中:https://ide.c9.io/captainzidane/kd_tree 将使用point.txt,test2.c,kdtree.c,kdtree.h。

这是我的" test.c"的一部分。文件,其中seg错误发生在最后一行。即最后一个右括号}

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include "kdtree.h"

#define DEF_NUM_PTS 10
#define MAX_NUM_OF_POINTS 20000
#define DIMENSION 3



    int main (int argc, char *argv[]) {
  //int arraySize; 
  double pointArray[MAX_NUM_OF_POINTS][DIMENSION];
  FILE *coordFile = fopen ("points.txt", "r");
  //coord *coords = malloc(sizeof(coord) * MAX_NUM_OF_POINTS);
  int lineCounter = 0;
  while (fscanf (coordFile, "%lf %lf %lf", &pointArray[lineCounter][0], &pointArray[lineCounter][1], 
                                           &pointArray[lineCounter][2]) == 3 && lineCounter < MAX_NUM_OF_POINTS) {
    lineCounter++;
  }
  double range = 8.1;
  int num_of_nearest;
  double queryPoint[DIMENSION];
  int counter;
  int dist;
  int num;
  //scanf ("%lf %lf %lf %d", &queryPoint[0], &queryPoint[1], &queryPoint[2], &num);
  queryPoint[0] = 1;
  queryPoint[1] = 5;
  queryPoint[2] = 8;
  num = 10;

  //Build and insert points to a KD Tree
  struct kdtree *newTree = buildTree (pointArray);//////make it run only once



  //Return nearst N nodes and distance in order from smallest to largest
  struct knn_result *res_n = knn(newTree, queryPoint, num);
  free (res_n);
  printf ("======================================================\n");


  //Return nodes within a range of the query point
  struct nn_range *res_range = nn_range(newTree, queryPoint, range);
  free (res_range);
  printf ("======================================================\n");


  fclose (coordFile);
  kd_free(newTree);///To be deleted
  return EXIT_SUCCESS;
} 

这是我&#34; kdtree.c&#34;的一部分。包含可能导致错误的函数的文件:

struct nn_range {
    double nearestRange[MAX_NUM_OF_POINTS][DIMENSION+1];
    int nPoints;
};

struct nn_range *nn_range (struct kdtree *tree, const double *queryPoint, double range) 
{

  printf ("Nodes within a radius of %.3f to the query point:\n", range);
  printf ("-------------------------------------------------\n");

  struct kdres *presults_range = kd_nearest_range(tree, queryPoint, range); 
  double temp[3] = {0};
  double dist_temp = 0;

  struct nn_range *res = malloc(sizeof(struct nn_range));

  int counter = 0,i;

  res->nPoints = kd_res_size(presults_range);
  printf("found %d results within the radius of %.3f\n", res->nPoints, range);

  while(!kd_res_end( presults_range) && counter < res->nPoints) 
  {
    dist_temp = 0;
    /* get the data and position of the current result item */
    kd_res_item(presults_range, temp);

    /* compute the distance of the current result from the pt */
    for(i=0; i<DIMENSION; i++) 
    {
        dist_temp += SQ(queryPoint[i] - temp[i]);
    }
    dist_temp = sqrt(dist_temp);
    res->nearestRange[counter][0] = temp[0];
    res->nearestRange[counter][1] = temp[1];
    res->nearestRange[counter][2] = temp[2];
    res->nearestRange[counter][3] = dist_temp;

    /* print out the retrieved data */
    printf("node at (%.3f, %.3f, %.3f) is %.3f away\n", res->nearestRange[counter][0], 
                                                        res->nearestRange[counter][1],
                                                        res->nearestRange[counter][2],
                                                        res->nearestRange[counter][3]);

    /* go to the next entry */
    kd_res_next(presults_range);
    counter++;
  }

  kd_res_free(presults_range);
  return res;
}

GDB说

    Program received signal SIGSEGV, Segmentation fault.
0x0000000000400ab9 in main (argc=1, argv=0x7fffffffe1d8) at test2.c:117
117     } 

Valgrind说

==5369== Jump to the invalid address stated on the next line
==5369==    at 0x3FE970FD6F3D35D2: ???
==5369==    by 0x3FED48EE17391B6D: ???
==5369==    by 0xFFF000157: ???
==5369==    by 0xFFFFFFFF: ???
==5369==    by 0x4008BC: ??? (in /home/ubuntu/workspace/KNN - GitHub/c)
==5369==  Address 0x3fe970fd6f3d35d2 is not stack'd, malloc'd or (recently) free'd
==5369== 
==5369== 
==5369== Process terminating with default action of signal 11 (SIGSEGV)
==5369==  Bad permissions for mapped region at address 0x3FE970FD6F3D35D2
==5369==    at 0x3FE970FD6F3D35D2: ???
==5369==    by 0x3FED48EE17391B6D: ???
==5369==    by 0xFFF000157: ???
==5369==    by 0xFFFFFFFF: ???
==5369==    by 0x4008BC: ??? (in /home/ubuntu/workspace/KNN - GitHub/c)
==5369== 
==5369== HEAP SUMMARY:
==5369==     in use at exit: 0 bytes in 0 blocks
==5369==   total heap usage: 40,057 allocs, 40,057 frees, 2,561,888 bytes allocated
==5369== 
==5369== All heap blocks were freed -- no leaks are possible
==5369== 
==5369== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==5369== 
==5369== 1 errors in context 1 of 1:
==5369== Jump to the invalid address stated on the next line
==5369==    at 0x3FE970FD6F3D35D2: ???
==5369==    by 0x3FED48EE17391B6D: ???
==5369==    by 0xFFF000157: ???
==5369==    by 0xFFFFFFFF: ???
==5369==    by 0x4008BC: ??? (in /home/ubuntu/workspace/KNN - GitHub/c)
==5369==  Address 0x3fe970fd6f3d35d2 is not stack'd, malloc'd or (recently) free'd
==5369== 
==5369== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault

这是输出的一部分

    Nodes within a radius of 8.100 to the query point:
-------------------------------------------------
found 24 results within the radius of 8.100
node at (0.718, 0.958, 0.994) is 8.093 away
node at (0.716, 0.974, 0.992) is 8.087 away
node at (0.629, 0.960, 0.991) is 8.099 away
node at (0.629, 0.960, 0.991) is 8.099 away
node at (0.556, 0.994, 0.979) is 8.096 away
node at (0.677, 0.985, 0.991) is 8.084 away
node at (0.556, 0.994, 0.979) is 8.096 away
node at (0.677, 0.985, 0.991) is 8.084 away
node at (0.909, 0.966, 0.980) is 8.097 away
node at (0.909, 0.966, 0.980) is 8.097 away
node at (0.909, 0.966, 0.980) is 8.097 away
node at (0.909, 0.966, 0.980) is 8.097 away
node at (0.978, 0.958, 0.993) is 8.089 away
node at (0.978, 0.958, 0.993) is 8.089 away
node at (0.978, 0.958, 0.993) is 8.089 away
node at (0.978, 0.958, 0.993) is 8.089 away
node at (0.857, 0.970, 0.978) is 8.098 away
node at (0.862, 0.985, 0.984) is 8.085 away
node at (0.862, 0.985, 0.984) is 8.085 away
node at (2.000, 2.000, 2.000) is 6.782 away
node at (2.000, 2.000, 2.000) is 6.782 away
node at (1.000, 1.000, 1.000) is 8.062 away
node at (1.000, 1.000, 1.000) is 8.062 away
node at (1.000, 2.000, 2.000) is 6.708 away
======================================================
Segmentation fault

1 个答案:

答案 0 :(得分:2)

  

一切都已执行后发生分段错误

在99.9%的情况下会发生这种情况,因为您溢出了main中分配的堆栈缓冲区,并踩到(损坏的)main的返回地址,因此它返回到“垃圾”地址。

  

我试了好几个小时但仍然找不到问题

有几种方法可以找到这样的问题:

  1. 代码检查。现在您知道要查找的内容,检查main中的所有堆栈缓冲区,并检查您是否没有写入任何超出界限的内容。
  2. main中的第一个堆栈缓冲区之前,以及最后一个缓冲区之后,分配256字节的额外缓冲区。使用已知的sentinel值填充这些额外缓冲区,并在从main返回之前验证sentinel值是否仍然完好无损。他们可能不会。一旦知道哪个哨兵值被破坏,请使用GDB观察点查找哪个代码写入该地址。
  3. Valgrind(您尝试过)在检测堆栈溢出时非常弱。您可以将一些堆栈缓冲区转换为堆分配,Valgrind会立即告诉您溢出发生的位置。
  4. 如果您有一个相对较新的编译器,Clang和GCC都支持Address Sanitizer-fsanitize=address),它非常适合检测堆堆栈溢出,并且很可能直截了当地指出问题。
  5.   

    所有代码都在“KNN - GitHub”目录下

    该网站需要登录。你不认真地相信我们所有人都会在那里注册一个帐户,这样我们就可以确切地告诉你问题是什么?下次,尝试将代码放在更容易访问的地方。