鱼C论坛

 找回密码
 立即注册
查看: 92|回复: 1

[已解决]【C语言】优先队列 段错误

[复制链接]
发表于 2024-4-27 21:44:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. /* priority_queue.h */
  2. #ifndef PRIORITY_QUEUE_H
  3. #define PRIORITY_QUEUE_H

  4. #include <stdbool.h> /* Only C99 */
  5. #include <stdint.h>  /* Only C99 */

  6. // Numbers
  7. #define PQUEUE_INIT_SIZE   10
  8. #define PQUEUE_GROW_FACTOR 5
  9. #define ERR_FLAG           -1

  10. // Types and modifiers
  11. #define PQUEUE_DATA_T      int
  12. #define SUBSCRIPT_T        int
  13. #define FLAG_T             int_least8_t
  14. #define PUBLIC             /* There are not anything */
  15. #define PRIVATE            static

  16. typedef struct {
  17.     size_t         cap;
  18.     size_t         size;
  19.     PQUEUE_DATA_T *node;
  20. } pqueue_t;

  21. /* heap:
  22. *       1>0
  23. *    2>1   3>2
  24. * 4>3 5>4 6>5 7->6
  25. * array subscript:
  26. * [1, 2, 3, 4, 5, 6, 7] (up to down, right to left)
  27. * parent: i, left son node: 2i + 1, right son node: 2i + 2
  28. */

  29. PUBLIC  bool          priority_queue_init(pqueue_t *pqueue);
  30. PUBLIC  bool          priority_queue_ins(pqueue_t *pqueue, PQUEUE_DATA_T data);
  31. PUBLIC  PQUEUE_DATA_T priority_queue_del(pqueue_t *pqueue);
  32. PUBLIC  bool          priority_queue_des(pqueue_t *pqueue);
  33. PRIVATE bool          is_empty(pqueue_t *pqueue);
  34. PRIVATE bool          is_full(pqueue_t *pqueue);

  35. #endif /* PRIORITY_QUEUE__H */
复制代码


  1. /* priority_queue.c */
  2. #include <stdlib.h>
  3. #include <limits.h>
  4. #include "priority_queue.h"

  5. PUBLIC bool priority_queue_init(pqueue_t *pqueue) {
  6.     pqueue->node = (PQUEUE_DATA_T *) malloc(PQUEUE_INIT_SIZE * sizeof (PQUEUE_DATA_T));
  7.     if (pqueue->node == NULL)
  8.         return false;
  9.     pqueue->cap  = PQUEUE_INIT_SIZE;
  10.     pqueue->size = 0;
  11.     return true;
  12. }

  13. PUBLIC bool priority_queue_ins(pqueue_t *pqueue, PQUEUE_DATA_T data) {
  14.     FLAG_T ret;
  15.     int i;
  16.     if (ret = is_full(pqueue)) {
  17.         pqueue->cap *= PQUEUE_GROW_FACTOR;
  18.         pqueue->node = (PQUEUE_DATA_T *) realloc(pqueue->node, pqueue->cap * sizeof (PQUEUE_DATA_T));
  19.         if (pqueue->node == NULL)
  20.             return false;
  21.     }
  22.     if (ret == ERR_FLAG)
  23.         return false;
  24.    
  25.     i = pqueue->size++;
  26.     while (i > 0) {
  27.         int parent = (i - 2) / 2;
  28.         if (data < pqueue->node[parent]) {
  29.             pqueue->node[i] = pqueue->node[parent];
  30.             i = parent;
  31.         } else
  32.             break;
  33.     }
  34.     /* i / 2 - 1 || i / 2 - 2: Compute parent node. */
  35.     pqueue->node[i] = data;
  36.     return true;
  37. }

  38. PUBLIC PQUEUE_DATA_T priority_queue_del(pqueue_t *pqueue) {
  39.     if (is_empty(pqueue))
  40.         return INT_MAX;
  41.    
  42.     PQUEUE_DATA_T root = pqueue->node[0];
  43.     pqueue->node[0]    = pqueue->node[pqueue->size - 1];
  44.     pqueue->size--;
  45.    
  46.     int i = 0;
  47.     while (i * 2 + 1 < pqueue->size) {
  48.         int minson = i * 2 + 1;
  49.         if (minson + 1 < pqueue->size && pqueue->node[minson] > pqueue->node[minson + 1])
  50.             minson++;
  51.         if (pqueue->node[i] > pqueue->node[minson]) {
  52.             pqueue->node[i] = pqueue->node[minson];
  53.             i = minson;
  54.         } else
  55.             break;
  56.     }
  57.    
  58.     return root;
  59. }

  60. PUBLIC bool priority_queue_des(pqueue_t *pqueue) {
  61.     if (pqueue == NULL)
  62.         return false;
  63.         
  64.     free(pqueue->node);
  65.     pqueue->node = NULL;
  66.     pqueue->cap  = 0;
  67.     pqueue->size = 0;
  68.     return true;
  69. }

  70. PRIVATE bool is_empty(pqueue_t *pqueue) {
  71.     if (pqueue == NULL)
  72.         return ERR_FLAG;
  73.     else if (pqueue->size == 0)
  74.         return true;
  75.     else
  76.         return false;
  77. }

  78. PRIVATE bool is_full(pqueue_t *pqueue) {
  79.     if (pqueue == NULL)
  80.         return ERR_FLAG;
  81.     else if (pqueue->size == pqueue->cap)
  82.         return true;
  83.     else
  84.         return false;
  85. }
复制代码

  1. /* priotity_queue_client.c */
  2. #include <stdio.h>
  3. #include "priority_queue.h"

  4. int main(void) {
  5.     pqueue_t *pqueue;
  6.     priority_queue_init(pqueue);
  7.    
  8.     for (int i = 0; i < 100; i++)
  9.         priority_queue_ins(pqueue, i);
  10.     for (int i = 0; i < pqueue->size; i++)
  11.         printf("%d\n", pqueue->node[i]);
  12.    
  13.     priority_queue_des(pqueue);
  14.     return 0;
  15. }
复制代码

输出:
段错误 (核心已转储)

环境:
Ubuntu 22.04.4 LTS
gcc:

  1. Using built-in specs.
  2. COLLECT_GCC=gcc
  3. COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
  4. OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
  5. OFFLOAD_TARGET_DEFAULT=1
  6. Target: x86_64-linux-gnu
  7. Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
  8. Thread model: posix
  9. Supported LTO compression algorithms: zlib zstd
  10. gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)
复制代码


有没有大佬帮忙看一下错在那啊ToT
最佳答案
2024-4-27 21:45:09
在您提供的代码中,存在几个问题导致段错误:

1. 在`priority_queue_client.c`文件中,您定义了一个指向`pqueue_t`类型的指针`pqueue`,但是没有为其分配内存空间。这导致在调用`priority_queue_init(pqueue)`函数时,会访问未初始化的指针,从而导致段错误。

解决方法:为`pqueue`指针分配内存空间。可以改为使用如下代码:
  1. pqueue_t pqueue;
  2. priority_queue_init(&pqueue);
复制代码


2. 在`priority_queue_ins`函数中,存在一处错误的赋值操作。以下代码是有问题的:
  1. pqueue->node = pqueue->node;
复制代码

应该将其改为:
  1. pqueue->node[i] = pqueue->node[parent];
复制代码


另外,还需要修改以下代码:
  1. pqueue->node = data;
复制代码

改为:
  1. pqueue->node[i] = data;
复制代码


3. 在`priority_queue_del`函数中,存在一处错误的赋值操作。以下代码是有问题的:
  1. pqueue->node = pqueue->node;
复制代码

应该将其改为:
  1. pqueue->node[i] = pqueue->node[minson];
复制代码


修复以上问题后,您的代码应该能够正常运行。希望对您有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-4-27 21:45:09 | 显示全部楼层    本楼为最佳答案   
在您提供的代码中,存在几个问题导致段错误:

1. 在`priority_queue_client.c`文件中,您定义了一个指向`pqueue_t`类型的指针`pqueue`,但是没有为其分配内存空间。这导致在调用`priority_queue_init(pqueue)`函数时,会访问未初始化的指针,从而导致段错误。

解决方法:为`pqueue`指针分配内存空间。可以改为使用如下代码:
  1. pqueue_t pqueue;
  2. priority_queue_init(&pqueue);
复制代码


2. 在`priority_queue_ins`函数中,存在一处错误的赋值操作。以下代码是有问题的:
  1. pqueue->node = pqueue->node;
复制代码

应该将其改为:
  1. pqueue->node[i] = pqueue->node[parent];
复制代码


另外,还需要修改以下代码:
  1. pqueue->node = data;
复制代码

改为:
  1. pqueue->node[i] = data;
复制代码


3. 在`priority_queue_del`函数中,存在一处错误的赋值操作。以下代码是有问题的:
  1. pqueue->node = pqueue->node;
复制代码

应该将其改为:
  1. pqueue->node[i] = pqueue->node[minson];
复制代码


修复以上问题后,您的代码应该能够正常运行。希望对您有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-6-3 23:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表