I
irqbreaker
Hi,
Could someone please show me the obvious error I've made in the
following code example?
First, this example compiles and executes without fail on both Linux
(gcc 4.2.1), and
Solaris (GCC 3.4.6). But I get an Segmentation fail when I compile and
run on Windows
with djgpp (GCC 4.2.1).
gdb says:
Program received signal SIGSEGV, Segmentation fault.
0x0000204c in listDeleteNode (n=0x8e52c) at fail.c:56
56 (*n)->next->prev = (*n)->prev;
I thought that the test on line 54 made sure that I wasn't trying to
dereference a bad
pointer.
Anyway, here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node
{
int value;
char *name;
struct Node *prev;
struct Node *next;
} Node;
void *xMalloc(size_t s)
{
void *res = malloc(s);
if(!res && s) {
fprintf(stderr, "malloc() failed\n");
exit(EXIT_FAILURE);
}
return res;
}
Node *listAddNode(Node **n, int value, char *name)
{
Node *new = xMalloc(sizeof(Node));
char *newName = xMalloc(strlen(name)+1);
new->value = value;
strcpy(newName, name);
new->name = newName;
if(!*n) {
*n = new;
(*n)->next = NULL;
(*n)->prev = NULL;
} else {
new->prev = *n;
(*n)->next = new;
*n = new;
}
return new;
}
void listDeleteNode(Node **n)
{
Node *d = *n;
if(!d)
return;
if(d->prev && d->next) {
(*n)->prev->next = (*n)->next;
(*n)->next->prev = (*n)->prev;
*n = (*n)->next;
} else if(!d->prev && d->next) {
(*n)->next->prev = NULL;
*n = (*n)->next;
} else if(d->prev && !d->next) {
(*n)->prev->next = NULL;
*n = (*n)->prev;
}
free(d->name);
free(d);
}
void listFree(Node **n)
{
Node *tmp;
if(!*n)
return;
while(*n) {
tmp = *n;
*n = (*n)->next;
free(tmp->name);
free(tmp);
}
}
int main(void)
{
Node *head = NULL;
Node *tail = NULL;
head = listAddNode(&tail, 1, "Hello");
listAddNode(&tail, 2, "World");
listDeleteNode(&tail);
listAddNode(&tail, 3, "ICANHAZCHEEZBURGER");
listFree(&head);
return EXIT_SUCCESS;
}
Best regards,
Peter
Could someone please show me the obvious error I've made in the
following code example?
First, this example compiles and executes without fail on both Linux
(gcc 4.2.1), and
Solaris (GCC 3.4.6). But I get an Segmentation fail when I compile and
run on Windows
with djgpp (GCC 4.2.1).
gdb says:
Program received signal SIGSEGV, Segmentation fault.
0x0000204c in listDeleteNode (n=0x8e52c) at fail.c:56
56 (*n)->next->prev = (*n)->prev;
I thought that the test on line 54 made sure that I wasn't trying to
dereference a bad
pointer.
Anyway, here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node
{
int value;
char *name;
struct Node *prev;
struct Node *next;
} Node;
void *xMalloc(size_t s)
{
void *res = malloc(s);
if(!res && s) {
fprintf(stderr, "malloc() failed\n");
exit(EXIT_FAILURE);
}
return res;
}
Node *listAddNode(Node **n, int value, char *name)
{
Node *new = xMalloc(sizeof(Node));
char *newName = xMalloc(strlen(name)+1);
new->value = value;
strcpy(newName, name);
new->name = newName;
if(!*n) {
*n = new;
(*n)->next = NULL;
(*n)->prev = NULL;
} else {
new->prev = *n;
(*n)->next = new;
*n = new;
}
return new;
}
void listDeleteNode(Node **n)
{
Node *d = *n;
if(!d)
return;
if(d->prev && d->next) {
(*n)->prev->next = (*n)->next;
(*n)->next->prev = (*n)->prev;
*n = (*n)->next;
} else if(!d->prev && d->next) {
(*n)->next->prev = NULL;
*n = (*n)->next;
} else if(d->prev && !d->next) {
(*n)->prev->next = NULL;
*n = (*n)->prev;
}
free(d->name);
free(d);
}
void listFree(Node **n)
{
Node *tmp;
if(!*n)
return;
while(*n) {
tmp = *n;
*n = (*n)->next;
free(tmp->name);
free(tmp);
}
}
int main(void)
{
Node *head = NULL;
Node *tail = NULL;
head = listAddNode(&tail, 1, "Hello");
listAddNode(&tail, 2, "World");
listDeleteNode(&tail);
listAddNode(&tail, 3, "ICANHAZCHEEZBURGER");
listFree(&head);
return EXIT_SUCCESS;
}
Best regards,
Peter