返回堆棧data-structure實現中pop函數的void**值

我的鍛煉狀態如下:

stack stack_push(stack s);
stack stack_pop(stack s, void **d);
//The second parameter of stack_pop function is requested in order to pass back to the caller the data fetched from the stack.

我在返回pop函數后移除的元素的值時遇到了問題:我無法返回移除元素的值,因為pop函數已經返回堆棧本身;因此,我應該使用void **d變量返回該值。

但當我試圖讀取STACK.C文件中的i變量時,出現了分段錯誤。(堆棧應該處理不同的數據類型,這就是為什么我使用了一個container結構,以便為數據類型存儲一個int(例如,1代表int,2代表float,etc.),以及void* value變量中的有效值)。

STACK.H

typedef struct _stack stack;
typedef struct _node node;
typedef struct _container container;

struct _node{
   void *data;
   struct _node *below;
};

struct _stack{
   node *base;
   node *top;
};

struct _container{
   int i;
   void *value;
};
#define STACK_EMPTY {NULL,NULL}

STACK.C

int main(){
   
   stack my_stack = STACK_EMPTY;
   
   ...

      switch(chose){
         case 1:
            my_stack = stack_push(my_stack);
            break;
         case 2:
            void **d = NULL; //d will contains the returned value.
            my_stack = stack_pop(my_stack, d);     
            container *cont = (container*)*d; 
            printf("%d", cont->i); //SEGMENTATION FAULT ERROR HERE
            break;
         case 3:
            stack_print(my_stack);
            break;
         default:
            break;
      }      
   }
}

STACK_OPERATIONS.H

#define MAX_STRING_SIZE 15

stack stack_push(stack s){
   ...
   int *push_int = malloc(sizeof(int));
   float *push_float = malloc(sizeof(float));;
   char *push_char = malloc(sizeof(char));;
   char *push_char_arr = malloc(sizeof(char)*MAX_STRING_SIZE+1);

   node *my_node = malloc(sizeof(struct _node));
   container *my_container = malloc(sizeof(struct _container));

   my_node->data = my_container;

   switch(chose_push){
      case 1:
         ...
         my_container->i = 1;
         my_container->value = push_int; 
      case 2:
         ...
         my_container->i = 2;
         my_container->value = push_float;
      case 3:
         ...
         my_container->i = 3;
         my_container->value = push_char;
      case 4:
         ...
         my_container->i = 4;
         my_container->value = push_char_arr;     
   }

   if(s.base == NULL && s.top == NULL){
      //Stack is empty
      my_node->below = NULL;
      s.base = my_node;
      s.top = my_node;
   } else {
      my_node->below = s.top;
      s.top = my_node;
   }
   return s;
}

stack stack_pop(stack s, void **d){
   if(s.base == NULL && s.top == NULL){
      //Stack is empty
      puts("Stack is empty: cannot execute pop.");
   } else {
      node *my_node_1 = s.top;
      node *my_node_2 = my_node_1;
      my_node_1 = my_node_1->below;
      
      d = my_node_2->data; //Here I'm assigning back the d variable
      
      free(my_node_2);
      
      s.top = my_node_1;
      if(my_node_1==NULL) s.base = NULL;
   }
   return s;
}
? 最佳回答:

對于初學者來說,這些無條件內存分配

stack stack_push(stack s){
   ...
   int *push_int = malloc(sizeof(int));
   float *push_float = malloc(sizeof(float));;
   char *push_char = malloc(sizeof(char));;
   char *push_char_arr = malloc(sizeof(char)*MAX_STRING_SIZE+1);
   //...

導致內存泄漏,因為堆棧中確實只使用了一個分配的對象。

結構struct _node的數據成員data的類型為void *

struct _node{
   void *data;
   struct _node *below;
};

而函數stack_pop的參數d的類型為void **

void **d

所以這個任務

d = my_node_2->data;

沒有什么意義。

相反,例如,你應該用main寫

     case 2:
        void *d = NULL; //d will contains the returned value.
        my_stack = stack_pop(my_stack, &d);     
        container *cont = (container*)d; 
        if ( cont != NULL ) printf("%d", cont->i); //SEGMENTATION FAULT ERROR HERE
        break;

在函數stack_pop

stack stack_pop(stack s, void **d){
   if(s.base == NULL && s.top == NULL){
      //Stack is empty
      puts("Stack is empty: cannot execute pop.");
      *d = NULL;
   } else {
      node *my_node_1 = s.top;
      node *my_node_2 = my_node_1;
      my_node_1 = my_node_1->below;
      
      *d = my_node_2->data; //Here I'm assigning back the d variable
      
      free(my_node_2);
      
      s.top = my_node_1;
      if(my_node_1==NULL) s.base = NULL;
   }
   return s;
}

對于原始代碼,main中聲明的指針d將按值傳遞給函數。因此,該函數處理指針值的副本,副本的更改不會影響原始指針的值。

您應該釋放main中指針dd所指向對象的數據成員所指向的已分配內存。

此外,如果結構類型的對象將通過指向函數的指針通過引用傳遞給函數,而不是通過自身傳遞,則效果會更好。

例如,函數stack_pop的聲明如下

int stack_pop(stack *s, void **d);
主站蜘蛛池模板: 在线观看午夜亚洲一区| 欧美日韩一区二区成人午夜电影 | 人妻AV中文字幕一区二区三区| 夜夜添无码试看一区二区三区| 亚洲国产AV无码一区二区三区| 亚洲无线码在线一区观看| 国产无吗一区二区三区在线欢| 日本一区二区视频| 亚洲av成人一区二区三区| 日韩人妻无码一区二区三区| 国产AⅤ精品一区二区三区久久| 国产成人无码精品一区不卡| 亚洲日韩AV无码一区二区三区人| 无码一区二区三区在线观看| 国产一区二区在线视频| 夜夜添无码一区二区三区| 成人精品一区二区三区不卡免费看| 亚洲AV无码一区二三区| 一区二区三区高清视频在线观看| 日本一区二区高清不卡| 日韩三级一区二区三区| 日韩精品国产一区| 日本一区二区三区不卡在线视频| 午夜视频在线观看一区二区| 在线精品自拍亚洲第一区| 亚洲午夜精品一区二区麻豆| 日本中文字幕一区二区有码在线| 在线精品国产一区二区三区| 中文字幕日韩一区二区三区不| 男人免费视频一区二区在线观看| 日本v片免费一区二区三区| 国产伦精品一区三区视频| 国产一区中文字幕在线观看| 成人国产精品一区二区网站| 久久毛片免费看一区二区三区| 国产一区二区福利| 一区二区三区在线观看| 国产精品一区二区四区| 亚洲国产成人久久一区WWW| 亚洲一区二区三区在线观看精品中文| 久久福利一区二区|