我的鍛煉狀態如下:
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;
}
對于初學者來說,這些無條件內存分配
導致內存泄漏,因為堆棧中確實只使用了一個分配的對象。
結構
struct _node
的數據成員data
的類型為void *
而函數
stack_pop
的參數d
的類型為void **
所以這個任務
沒有什么意義。
相反,例如,你應該用main寫
在函數
stack_pop
中對于原始代碼,main中聲明的指針
d
將按值傳遞給函數。因此,該函數處理指針值的副本,副本的更改不會影響原始指針的值。您應該釋放main中指針
d
和d
所指向對象的數據成員所指向的已分配內存。此外,如果結構類型的對象將通過指向函數的指針通過引用傳遞給函數,而不是通過自身傳遞,則效果會更好。
例如,函數
stack_pop
的聲明如下