【问题标题】:Sorting a dynamic array in c在c中对动态数组进行排序
【发布时间】:2013-07-21 21:24:03
【问题描述】:

我正在尝试创建一个函数,以便使用“malloc”和“realloc”创建升序列表。

结构如下:

struct sorted_dyn_array {
  int *array;
  int length;
  int capacity;
};

返回一个指向 sorted_dyn_array 结构的指针,在堆上分配

const int BUFFER_INIT_SIZE = 5;
const int KEY_NOT_FOUND = -1;


struct sorted_dyn_array *arr_create(void) {
   struct sorted_dyn_array *new_arr = malloc(sizeof (struct sorted_dyn_array));
   new_arr->array = malloc(sizeof (int) * BUFFER_INIT_SIZE);
   new_arr->length = 0;
   new_arr->capacity = 5;
   return new_arr;
}

释放内存:

void free_arr(struct sorted_dyn_array *arr) {
  free(arr->buffer);
  free(arr);
}

int arr_length(struct sorted_dyn_array * arr) {
  return arr->length;
}

int arr_capacity(struct sorted_dyn_array *arr) {
  return arr->capacity;
}

使用二分查找找到下一个数字的位置:

int find_pos(int item, int arr[], int len) {
 int low = 0;
 int high = len-1;
 if (arr[0] >= item) {
 return 0;
 }
 if(arr[0] < item) {
 return KEY_NOT_FOUND;
 }
 while (low <= high) {
   int mid = low + (high - low) / 2;
   if (arr[mid] == item) {
   return mid;
   } else if (arr[mid] < item) {
   low = mid + 1;
   } else {
   high = mid - 1;
   }
   if(arr[high] < item) {
   return high;
   }
   }
   return KEY_NOT_FOUND;
 }


int arr_find_successor(struct sorted_dyn_array *arr, int k) {
  int len = arr_length(arr);
  return find_pos(k,arr->buffer,len);  
}

插入一个数字,如果它已经在列表中,则返回false。否则,在列表中插入一个数字,然后返回 true

bool arr_insert(struct sorted_dyn_array *arr, int k) {
  int pos = arr_find_successor(arr,k);
  if(arr_length(arr) == arr_capacity(arr)) {
  arr->capacity *= 2;
  arr->array = realloc(arr->buffer, sizeof(int) * arr->capacity);// realloc if the     length exceed the capacity
}
if (pos == KEY_NOT_FOUND) {// If the number is greater than all the number in array,put it at the end
  int l = arr->length;
  arr->array[l] = k;
  arr->length++;
  }
  if (pos != KEY_NOT_FOUND){
   for (int c = arr->length - 1; c >= pos; c--)
      arr->array[c+1] = array->array[c];
      arr->array[pos] = k;
      arr->length++;
   }
   return true;
}

主要功能:

int main () {
  struct sorted_dyn_array *myarray = arr_create();

  int next = 0;
  while (scanf("%d",&next) == 1) {
    int next_item = next;
    arr_insert(myarray, next_item);
    printf("%d\n",next_item);

   free_arr(myarray);
 }
}

但是,当我尝试扫描它显示的第二个数字时

    int arr_length(struct sorted_dyn_array * arr) {
      return arr->length;
    }

访问内存无效。有人可以帮帮我吗?我花了整整一个下午,仍然找不到哪里出了问题。提前致谢。

【问题讨论】:

  • +1 表示彻底的尝试。
  • 你考虑过使用 Valgrind 吗?
  • arr_create() 中的 5 应该是 BUFFER_INIT_SIZE
  • 在数组为空时读取find_posarr[0] 的值是未定义的行为。
  • 查看find_pos 中的实际比较:整数的基本属性arr[0] &gt;= itemarr[0] &lt; item 为真。 while 循环永远不会到达。

标签: arrays c dynamic heap-memory


【解决方案1】:

main 中循环结束时对free_arr 的调用意味着第二次迭代在调用arr_length 时对释放的内存进行操作。

这会导致未定义的行为,但您很幸运能够如此迅速地崩溃。您是否正在运行 Windows 调试版本? (这会将释放的内存设置为已知的“坏”值 - 0xFEEEFEEE - 以帮助您发现此类问题。)

这里的修复很简单 - 只需将 free_arr(myarray) 调用移到循环之外。

int main () {
    struct sorted_dyn_array *myarray = arr_create();

    int next = 0;
    while (scanf("%d",&next) == 1) {
        int next_item = next;
        arr_insert(myarray, next_item);
        printf("%d\n",next_item);
    }
    free_arr(myarray);
}

【讨论】:

  • 我收到了sdl(21291) malloc: *** error for object 0x7fb14bc03a50: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug 消息。代码编译后,您的修复确实可以解决问题。
猜你喜欢
  • 2011-04-23
  • 2013-12-24
  • 2013-08-05
  • 2013-05-25
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 2014-12-31
相关资源
最近更新 更多