【问题标题】:Working with pointers: program that sorts an integer array, segmentation fault使用指针:对整数数组进行排序的程序,分段错误
【发布时间】:2017-03-27 14:02:38
【问题描述】:

我正在尝试制作一个具有以下属性的程序: 具有原型 int*max_sorted(int array[], int laenge, int max) 的程序,它对数组中的整数进行排序。在堆上创建一个大小为 max+1 的整数数组,并用零填充所有位置。然后读取给函数的数组。如果读取整数 x,则堆上位置 x 处的数组的值增加 1。然后数组被覆盖:如果读取堆上数组的位置 i 处的值 n,则将 i 在数组中写入 n 次(当前位置)。下面的代码给出了分段错误:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int *max_sorted(int array[],int laenge, int max){
  int k,l;
  int *ptr;

  ptr= malloc((max+1)*sizeof(int)); /*allocates memory for new array*/
  if(ptr==NULL || max<0){
    return NULL;   /*error*/
  }
  for(k=0; k<max+1; k++){      /*sets all values of ptr array to 0*/
    ptr[k]=0; 
  }


  for(k=0;k<laenge;k++){               
    ptr[array[k]]++;      
   }



  for(k=0;k<max+1;k++){
    if(ptr[k]!=0){
    array[k-l]=k*ptr[k]; 
    }
    else{
      l++;
    }
  }




  free(ptr);
  return array;
}





int main(void){


  int array[3]={2,1,3};
  int laenge=3;
  int max=3;
  int k;
  int*ptr;
  ptr=max_sorted(array,laenge,max);
   for(k=0;k<laenge;k++){
    printf("%d",ptr[k]);
   } 



    return 0;
}

编辑:现在可以正常工作的更正版本可以在下面查看:

int *max_sorted(int array[],int laenge, int max){
  int k;
  int l=0;
  int *ptr;
  int i=0;

  ptr= malloc((max+1)*sizeof(int)); /*allocates memory for new array*/
  if(ptr==NULL || max<0){
    return NULL;   /*error*/
  }
  for(k=0; k<max+1; k++){      /*sets all values of ptr array to 0*/
    ptr[k]=0; 
  }


  for(k=0;k<laenge;k++){               
    ptr[array[k]]++;      
   }


  for(k=0;k<max+1;k++){
    l=ptr[k];
    while(l>0){
      array[i]=k;
      i++;
      l--;
    }

  }


  free(ptr);
  return array;
}

【问题讨论】:

  • max_sorted 中,l 变量永远不会被初始化。
  • 天哪,我太笨了……谢谢!
  • 你为什么有max laenge。你的数组只有一个长度。
  • @MichaelWalz ptr 指向一个数组,该数组计算array 中每个值的实例数。 maxarray 中的最大值相同。不过我不明白算法的其余部分。
  • @JeremyP PS:如果数组中的数字不重复,算法似乎工作正常。

标签: c arrays loops sorting pointers


【解决方案1】:

编辑后的发布代码仍然不正确。

这是一个版本的代码

  1. 干净编译
  2. 执行所需的功能
  3. 仍然依赖于数组的内容来避免未定义的行为

现在是代码

#include <stdio.h>   // printf()
#include <stdlib.h>  // calloc(), free(), exit(), EXIT_FAILURE



int *max_sorted(int array[], 
                size_t laenge, 
                size_t numElementsInArray);



int main( void )
{
    int array[] = { 2,1,3 };
    size_t laenge=3;

    size_t k;
    int*ptr;

    ptr=max_sorted( array, laenge, sizeof( array )/sizeof(int) );

    for( k=0; k<(sizeof( array )/sizeof(int)); k++)
    {
        printf( "%d ", ptr[k] );  //<-- note space in format string
    }

    return 0;         // <-- in modern C, when main returns 0, this line not needed
} // end function: main


int *max_sorted( int array[],      // array to be sorted
                 size_t laenge,    // largest value in array
                 size_t numElementsInArray ) 
{
    int *ptr = calloc( numElementsInArray+1, sizeof(int) ); /*allocates memory for new array*/
    if(!ptr)
    { // then calloc failed
        perror( "calloc for temporary array failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    for( size_t i=0; i<laenge; i++ )
    {
        ptr[ array[i] ]++;      // <-- this will have undefined behavior
                                //     when array[i] > 3
    }

    size_t index2 = 1;
    for( size_t index1=1; index1<(numElementsInArray+1); index1++ )
    {
        if( ptr[index1] )
        {
            array[index1-index2] = (int)index1 * ptr[index1];
        }

        else
        {
            index2++;
        }
    }

    free(ptr);
    return array;
} // end function: max_sorted

上面代码的输出是:

1 2 3 

【讨论】:

  • 注意:如果main() 中的行更改为:int array[] = { 2,1,310 }; size_t laenge=310;,则当前答案将导致段错误事件。所以现在的逻辑是不正确的。因此您需要将第二个参数澄清为max_sorted() 或修改逻辑
最近更新 更多