Я пишу стек, который является связанным списком данных (тип void). Данные, которые я тестирую,
struct my_data {
int val;
char name[60];
};
struct my_stack_node {
void *data;
struct my_stack_node *next;
};
struct my_stack {
int size;
struct my_stack_node *first;
};
данные, используемые для отправки, инициализируются следующим образом:
s1 = my_stack_init(sizeof(struct my_data));
if (!s1) {
puts("Error in my_stack_init()");
exit(1);
}
printf("\ns1 initialized, size of data: %lu\n", sizeof(struct my_data));
for (int i = 0; i < NODES; i++) {
data = malloc(sizeof(struct my_data)); // We must allocate static memory
data->val = i;
sprintf(data->name, "Value %d", i);
if (my_stack_push(s1, data)) {
puts("Error in my_stack_push()");
exit(1);
}
} //s1 is the stack we are using here
И толкать их с помощью my_stack_push (s2, data); стек и данные в качестве аргументов.
Моя функция нажатия:
int my_stack_push(struct my_stack *stack, void *data){
if(stack == NULL && sizeof(data)> 0){
printf("Null Stack or data size error.\n");
//la pila debe existir
return -1;
}
else {
struct my_stack_node *nodeToPush = malloc(sizeof(struct my_stack_node));
nodeToPush -> data = data;
if(stack -> first == NULL) {
nodeToPush -> next = NULL;
stack -> first = nodeToPush;
}
else {
nodeToPush -> next = stack -> first;
stack -> first = nodeToPush;
}
}
return 0;
}
И моя поп-функция вот такая
void *my_stack_pop(struct my_stack *stack){
struct my_stack_node *node = stack->first;
if(stack->first == NULL){
return 0;
}
stack->first = node->next;
void *ret = node->data;
free(node);
return ret;
}
Но в моем основном случае, когда я высовываю их и пытаюсь сравнить их, я получаю ошибку сегментации:
while ((data1 = my_stack_pop(s1))) {
data2 = my_stack_pop(fs1);
printf("Node of s1: (%d, %s)\t", data1->val, data1->name);
printf("Node of fs1: (%d, %s)\n", data2->val, data2->name);
if (!data2 || data1->val != data2->val || my_strcmp(data1->name, data2->name)) {
printf("Data in s1 and fs1 are not the same.\n (data1->val: %d <> data2->val: %d) o (data1->name: %s <> data2->name: "
"%s)\n",
data1->val, data2->val, data1->name, data2->name);
exit(1);
}
size1 = sizeof(*data1);
size2 = sizeof(*data2);
free(data1);
free(data2);
}
printf("size of data from s1: %d\t", size1);
printf("size of data from fs1: %d\n", size2);
(2 стека являются копиями друг друга, поэтому то, что я сделал, должно быть таким же, как я читал). Когда я возвращаю весь узел в функции pop (не данные, а весь my_stack_node), все верно ... но неправильно:
Comparing the data...
Узел s1: (0, значение 0) // хороший
Узел fs1: (0, значение 0)
8
8
Узел s1: (-1203217792, NV) // здесь все начинает идти не так
Узел fs1: (-1203217792, NV)
8
8
Узел s1: (-1203217792, NV)
Узел fs1: (-1203217792, NV)
8
8
Узел s1: (-1203217792, NV)
Узел fs1: (-1203217792, NV)
8
8
Узел s1: (0,)
Узел fs1: (0,)
двойное освобождение или коррупция (fasttop)
Прервано (ядро сброшено)
Размер совпадает с введенными данными, но значение и имя неверны (даже в не скопированном стеке), что должно быть:
New node in s1: (0, Value 0)
New node in s1: (1, Value 1)
New node in s1: (2, Value 2)
New node in s1: (3, Value 3)
New node in s1: (4, Value 4)
New node in s1: (5, Value 5)
New node in s1: (6, Value 6)
New node in s1: (7, Value 7)
New node in s1: (8, Value 8)
New node in s1: (9, Value 9)
Но когда я возвращаю (в моем стеке) сами данные, как в коде, я выгружаю ядро при печати теста (данные, которые имеют длину 8 байтов, как один вход).
Когда я возвращаю узел (размер = 64), он правильно печатает неверные данные, но когда я возвращаю данные (размер = 8 (например, нажатый)), происходит сбой ядра.
Если я нажимаю одни и те же данные и читаю одни и те же данные (как это показано, когда я возвращаю узел, потому что даже при странном выводе они совпадают), почему я получаю ошибку сегментации ядра, когда возвращаю данные, которые должны быть напечатаны как в примере выше?
Похоже, это происходит только тогда, когда я читаю данные2, а не данные1. Это код, который я использую для записи и чтения файла:
Запись:
int my_stack_write(struct my_stack *stack, char *filename){
int count = 0;
struct my_stack_node *aux =malloc(sizeof(struct my_stack_node));
FILE *file = fopen(filename, "wb");
if(stack->first != NULL){
aux = stack->first;
count++;
while(aux->next != NULL){
printf("New node in s1: (%p)\n", aux->data);
fwrite(aux ,sizeof(struct my_stack_node), 1, file);
aux = aux->next;
count++;
}
printf("New node in s1: (%p)\n", aux->data);
fwrite(aux ,sizeof(struct my_stack_node), 1, file);
}
fclose(file);
return count;
}
Читать:
struct my_stack *my_stack_read(char *filename){
struct my_stack *stackRead = my_stack_init(sizeof(struct my_stack_node));
struct my_stack_node *stackNode = malloc(sizeof(struct my_stack_node));
FILE *file = fopen(filename, "rb");
if(!file){
puts("Impossible obrir el fitxer");
return NULL;
}else{
while(fread(stackNode, sizeof(struct my_stack_node), 1, file)){
printf("New node in fs1: (%p)\n", stackNode->data);
stackNode = (struct my_stack_node*) stackNode;
my_stack_push(stackRead, stackNode->data);
}
fclose(file);
struct my_stack *InvertedStack = my_stack_init(sizeof(struct my_stack_node));
struct my_stack_node *aux = malloc(sizeof(struct my_stack_node));
while(my_stack_len(stackRead) !=0){
printf("Inverting the stack\n");
aux = my_stack_pop(stackRead);
my_stack_push(InvertedStack, aux);
}
return InvertedStack;
}
}
Спасибо всем, кто помогает.
MCVE программы, чтобы люди могли проверить весь код и помочь лучше:
test2.c:
https://codeshare.io/244eN4
my_lib.c:
https://codeshare.io/G7L8Ab
my_lib.h:
https://codeshare.io/5DzZOm
При этом у вас должно быть более широкое представление и исполняемый файл после компиляции того, что со мной происходит.