使用gcc / ubuntu的if子句中的分段错误

时间:2013-10-03 13:41:42

标签: python c gcc

我正在编写一个用于python的c函数。当运行时发生分段故障,根据printf调用,它会被抛出if子句。 shell的输出是:

row 1, col 0: 1.000000
row:0, -col:0, index:0
-2: 0.000000
else
row:0, -col:1, index:1
-2: 0.000000
else
row:0, -col:2, index:2
-2: 0.000000
else
row:0, -col:3, index:3
-2: 0.000000
else
row:0, -col:4, index:4
-2: 0.000000
else
row:1, -col:0, index:5
-2: 1.000000
Speicherzugriffsfehler (Speicherabzug geschrieben)

(最后一行表示分段错误)

和c代码是:

#include <stdio.h>
#include <math.h>

#define pi 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

void hough(const void* img, int imgRowCount, int imgColCount, const void* thetas, int thetaCount, const void* rhos, int rhoCount, void* out)
{

  const double* imgD = (double*) img;
  double* outD = (double*)out;

  const double* thetasD = (double*)thetas;
  const double* rhosD = (double*)rhos;



  printf("row 1, col 0: %f\n", imgD[getIndex(1, 0, imgColCount)]);


  int row, col, thetaInd, rhoInd, index;
  double rhoVal, minDiff, diff, tmp;
  for(row = 0; row<imgRowCount; row++)
  {
      for(col = 0; col<imgColCount; col++)
      {
          printf("row:%d, -col:%d, index:%d\n", row, col, getIndex(row, col, imgColCount));
          tmp = imgD[getIndex(row, col, imgColCount)];
          printf("-2: %f\n", tmp);
          if (tmp>0.0)
          {
              printf("-1");
              for(thetaInd = 0; thetaInd<thetaCount; thetaInd++)
              {
                  rhoVal = col*cos(thetasD[thetaInd]*(pi/180)) + row*sin(thetasD[thetaInd]*(pi/180));
                  minDiff = INFINITY;
                  index = -1;
                  for(rhoInd = 0; rhoInd<rhoCount; rhoInd++)
                  {
                      diff = abs(rhoVal-rhosD[rhoInd]);
                      if(diff<minDiff)
                      {
                          minDiff = diff;
                          index = rhoInd;
                      }
                  }
                  if(index>=0)
                  {
                    printf("1\n");
                    outD[getIndex(index, thetaInd, thetaCount)] += 1;
                  }
              }
          }
          else
          {
            printf("else\n");
          }
      }

  }


}



int getIndex(int row, int col, int maxCol)
{
    return col + row*maxCol;
}

最后使用了python代码:

import numpy as np
import ctypes
from scipy.misc import imread



def makeReady(arr):
  return np.require(arr, dtype=np.double, requirements=["C_CONTIGUOUS"])



def hough(imgBin, thetaRes=1, rhoRes=1):
  if len(imgBin.shape) > 2:
    imgBin = np.mean(imgBin, axis=2)

  if imgBin.max() > 1:
    imgBin /= imgBin.max()

  if ((imgBin!=0) * (imgBin!=1)).sum()>0:
    imgBin = imgBin > (imgBin.max()/2.0)

  nR,nC = imgBin.shape
  theta = np.linspace(-90.0, 90.0, np.ceil(180.0/thetaRes) + 1.0)
  D = np.sqrt((nR - 1)**2 + (nC - 1)**2)
  q = np.ceil(D/rhoRes)
  nrho = 2*q + 1
  rho = np.linspace(-q*rhoRes, q*rhoRes, nrho)
  H = np.zeros((len(rho), len(theta)))


  imgC = makeReady(imgBin)
  thetasC = makeReady(theta)
  rhosC = makeReady(rho)
  outC = makeReady(H)


  lib = ctypes.cdll.LoadLibrary("./hough.so")
  lib.hough(imgC.ctypes.data_as(ctypes.c_void_p), imgC.shape[0], imgC.shape[1], thetasC.ctypes.data_as(ctypes.c_void_p), len(thetasC), rhosC.ctypes.data_as(ctypes.c_void_p),outC.ctypes.data_as(ctypes.c_void_p))



if __name__ == "__main__":
  img = 1 - (imread("lines.jpeg"))>125
  print img.shape
  a = np.zeros((5,5))
  a[1,0] = 5
  hough(a)
我在做错了什么? 谢谢

2 个答案:

答案 0 :(得分:0)

看起来唯一可能导致错误的是数组上的超出限制。使用getIndex(...)内部的[]功能可能会导致您的问题。

但是,由于难以阅读代码(没有注释,没有上下文),我建议使用调试器(如valgrind)为您提供有关错误位置的信息。实际上,valgrind甚至会打印出现错误的行号,只要您使用调试符号(gcc和clang上的-g -O0)进行编译即可。

答案 1 :(得分:0)

从输出中,错误似乎发生在代码的这一部分:

          for(thetaInd = 0; thetaInd<thetaCount; thetaInd++)
          {
              rhoVal = col*cos(thetasD[thetaInd]*(pi/180)) + row*sin(thetasD[thetaInd]*(pi/180));
              minDiff = INFINITY;
              index = -1;
              for(rhoInd = 0; rhoInd<rhoCount; rhoInd++)
              {
                  diff = abs(rhoVal-rhosD[rhoInd]);
                  if(diff<minDiff)
                  {
                      minDiff = diff;
                      index = rhoInd;
                  }
              }

              if(index>=0)
              {
                printf("1\n");
                outD[getIndex(index, thetaInd, thetaCount)] += 1;
              }
          }

只有在三个数组(thetasDrhosD以及outD)中的一个访问其范围之外,才会导致分段违规。

只有当索引运行到远时才会发生这种情况,而这反过来只有在for循环的中断条件错误时才会发生,这种情况只有在错误的值传递给hough时才会发生。 / p>

后者确实是这种情况,因为缺少Python脚本来传递rho的大小,虽然没有为outD传递任何内容。

这一行:

lib.hough(imgC.ctypes.data_as(ctypes.c_void_p), imgC.shape[0], imgC.shape[1], 
  thetasC.ctypes.data_as(ctypes.c_void_p), len(thetasC), 
  rhosC.ctypes.data_as(ctypes.c_void_p), 
  outC.ctypes.data_as(ctypes.c_void_p))

应该是这样的:

 lib.hough(imgC.ctypes.data_as(ctypes.c_void_p), imgC.shape[0], imgC.shape[1],
   thetasC.ctypes.data_as(ctypes.c_void_p), len(thetasC), 
   rhosC.ctypes.data_as(ctypes.c_void_p), len(rhosC), 
   outC.ctypes.data_as(ctypes.c_void_p))