如何解决C中的分段错误

时间:2014-10-02 06:55:41

标签: c gcc

因此,这是打印出给定数据集的垂直直方图的代码。 这里的数据在一个文件中,并且#34; H.in"用于在使用scanf时导入输入。输入的示例如下:

29
6 3 8 6 7 4 8 9 2 10 4 9 5 7 4 8 6 7 2 10 4 1 8 3 6 3 6 9 4

其中29是图表的数字,其余是需要转换为频率的数据。 检查程序保存数字,然后将其作为文件的输入。

基本上当我执行它时会出现分段错误。 现在我的理解是它是由于自由浮点或数组维度中的错误引起的......我试图搜索并解决问题,但我失败了,因为我找不到错误..

代码:

#include <stdio.h>
#include <stdlib.h>
//somewhere there is a segmentation fault. 
int *readGrades(int num) {
  int q;
  int *grades[num];
  for (q=0;q<num;q++){
      scanf("%d",grades[q]);//this is taking input for each element and storing it
      }

  return *grades;
}

int arrayMax(int arr[]) {
  int i, max = arr[0];
  for (i=0; i < 9; i++) {
       if (arr[i] > max) {
           max = arr[i];
              }
          }
    return max;
  }

void printHistogram(int freq[10], int *max)/*maxneeds to be added here?*/ {
int x,y, maxi;
maxi = *max;
for(x=0;x<maxi;x++){
  for(y=0;y<10;y++){
      if (freq[y] >= maxi){
          printf("* ");
          }
      else{
          printf(". ");
          }
       }
      printf("\n");
  }
printf("1 2 3 4 5 6 7 8 9 10 \n");
}

void computeFrequencies(int *grades[]) {
int a;
int freq[10]={0,0,0,0,0,0,0,0,0,0};

for(a=0;a<(sizeof(*grades)/sizeof(*grades[0]));a++){
switch(*grades[a]){
  case 1:
  freq[0]= freq[0]+1;
    break;
  case 2:
  freq[1]= freq[1]+1;
    break;
  case 3:
  freq[2]= freq[2]+1;
    break;
  case 4:
  freq[3]= freq[3]+1;
    break;
  case 5:
  freq[4]= freq[4]+1;
    break;
  case 6:
  freq[5]= freq[5]+1;
    break;
  case 7:
  freq[6]= freq[6]+1;
    break;
  case 8:
  freq[7]= freq[7]+1;
    break;
  case 9:
  freq[8]= freq[8]+1;
    break;
  case 10:
  freq[9]= freq[9]+1;
    break;
   }
}
int *u;
*u = arrayMax(freq);
printHistogram(freq, *(&u));
}

int main(int argc, char *argv[]) {
 int *grades;
 int num;
 scanf("%d",&num);/* this is the number of numbers*/
 grades = readGrades(num);
 computeFrequencies(&grades);
 return 0;
 }

1 个答案:

答案 0 :(得分:1)

在您的函数中

computeFrequencies(int *grades[])

for(a=0;a<(sizeof(*grades)/sizeof(*grades[0]));a++){

不会做你认为会做的事情,sizeof(*等级)给你一个int ptr的大小,因为* grades []会衰减成一个int **指针。

而是将数组的大小作为单独的参数传递

computeFrequencies(int *grades[], size_t gradeArraySize)

更严重的是,此函数返回局部变量的地址:

int *readGrades(int num) 
{
  int q;
  int *grades[num];
  for (q=0;q<num;q++){
      scanf("%d",grades[q]);//this is taking input for each element and storing it
      }

  return *grades;
}

返回你需要的数组,通常需要分配内存并返回一个指向它的内存,或者将内存传递给存储器,将值存储为具有一些最大大小的参数,或者如果值的数量大于适合的值则分配然后重新分配进入内存块。

在你的情况下,最简单的是给出最大尺寸(例如,未编译)

size_t readGrades(size_t maxgrades, int *grades) 
{
  // use fgets to read from the keyboard
  int actualSize = 0;
  char buffer[128];
  if (fgets( buffer, sizeof(buffer), stdin ) != NULL && actualSize < maxgrades)
  {
    for (char* p = strtok(buffer, " "); p != NULL; p = strtok(NULL, " ")
    {
      grades[actualSize++] = atoi(p); // convert to number
    }
  }
  return actualSize;
}

关于开关,它可以重写为

for (int i = 0; i < gradeArraySize; ++i)
{
  freq[ grades[i] - 1 ]++;
}

如果成绩为1-10,而freq被声明为int freq[10] = {0};

<强> EDIT2

如果要从函数返回数组,可以通过以下几种方式完成。

最简单但效率最低的方法是返回数组的副本:

typedef struct
{
  int grades[100];
} returnarray;

returnarray foo()
{
  returnarray ar;
  ar.grades[0] = 42;
  ...
  return ar;
}

或更有效

int foo(int **array)
{
  ...
  size_t size = 10;
  *array = malloc( size * sizeof(int) ); // changing what array points to
  ...
  *array[0] = 42; // assigning an int in the array
  ...

  return size; 
}

<强> EDIT3

要返回具有动态大小的数组,您可以像这样写

char** getLines()
{
   const int maxLineLength = 32;
   char** lines = malloc( 11 * sizeof(char*) ); // note the extra pointer 10+1
   for (int i = 0; i < 10; ++i)
   {
     lines[i] = malloc( maxLineLength );
     strcpy( lines + i, "hello" );
   }
   lines[10] = NULL;
   return lines;
}

呼叫者

char** lines = getLines();

for (int i = 0; lines[i] != NULL; ++i)
{
  puts( lines[i] );
}