Hey i am starting to work on Huffman coding and I have a bit of a problem I getting this error
Segmentation fault (core dumped)
I understand it is caused by trying to reach memory you are not allow to but I can not realize what is the problem in my code, thank in advnace for the help!
src.txt - http://pastebin.com/kDf8nEhV
#include <stdio.h>
#include <stdlib.h>
int freq[256] = {0};
struct Node {
unsigned char m_ch;
int m_freq;
struct Node* m_ls, *m_rs;
struct Node* m_hls, *m_hrs;
};
struct Node* createNode(int freq, char ch);
void insertTree(struct Node** root, struct Node* n);
struct Node* getBinTree(FILE* fsrc);
void inorder(struct Node* root);
int main() {
FILE* fsrc;
struct Node* tree = (struct Node*)malloc(sizeof(struct Node));
fsrc = fopen("src.txt", "rb");
tree = getBinTree(fsrc);
inorder(tree);
return 1;
}
struct Node* createNode(int freq, char ch) {
struct Node* pNode = (struct Node*)malloc(sizeof(struct Node));
pNode->m_freq = freq;
pNode->m_ch = ch;
return pNode;
}
void insertTree(struct Node** root, struct Node* n) {
if (!(*root)) {
*root = n;
return;
}
if (n->m_freq < (*root)->m_freq) {
insertTree(&(*root)->m_ls, n);
} else {
insertTree(&(*root)->m_rs, n);
}
}
struct Node* getBinTree(FILE* fsrc) {
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
struct Node** root = (struct Node**)malloc(sizeof(struct Node*));
*root = (struct Node*)malloc(sizeof(struct Node));
int c, i;
while ((c = fgetc(fsrc)) != EOF) {
freq[c]++;
}
freq[255] = 1;
fclose(fsrc);
for (i = 0; i < 256; i++) {
if (freq[i] > 0) {
temp = createNode(freq[i], i);
insertTree(root, temp);
}
}
}
void inorder(struct Node* root) {
if (root != NULL) {
inorder(root->m_ls);
printf(" %d\n", root->m_freq);
inorder(root->m_rs);
}
return;
}
Your,
struct Node* getBinTree(FILE *fsrc)
is not returning anything.
You should enable compiler warnings, the compiler would have told you about that, the function is not returning a value, but you still assign it to tree in main().
But apart from that there is a serious problem with your code, a simple example
int main()
{
FILE *fsrc;
struct Node *tree = (struct Node*)malloc (sizeof(struct Node));
fsrc = fopen("src.txt","rb");
tree=getBinTree(fsrc);
inorder(tree);
return 1;
}
This single function has many problems,
You allocate new memory and point to it with tree, but you never use it because you overwrite the pointer here
tree = getBinTree(fsrc);
that causes a memory leak.
You don't check if the file was succesfuly opened, you must check
fsrc = fopen("src.txt", "rb");
if (fsrc == NULL)
return -1;
You don't need to cast malloc()
struct Node *tree = malloc(sizeof(*tree));
this is more robust, and easier to read.
You have to make sure that malloc() did not fail to allocate memory, when it does NULL is returned, so you need this when you do a malloc() that is actually required, for example in getBinTree()
struct Node *tree = malloc(sizeof(*tree));
if (tree == NULL)
return NULL;
i.e., copy malloc()'s behavior by returning NULL on failure.
Related
I am unable to understand what the problem is as it isn't giving the correct output
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node*next;
};
void traversal(struct node*ptr){
while(ptr!=NULL){
printf("Element is: %d\n",ptr->data);
ptr=ptr->next;
}
}
void read(struct node*head){
FILE*file;
int val;
struct node*cur=(struct node*)malloc(sizeof(struct node));
head=cur=NULL;
file=fopen("list.txt","r");
while(fscanf(file,"%d",&val)!=EOF){
struct node*ptr=(struct node*)malloc(sizeof(struct node));
ptr->data=val;
ptr->next=NULL;
if(head==NULL){
head=cur=ptr;
}
else{
cur=cur->next=ptr;
}
}
fclose(file);
}
int main(){
struct node* head;
//Allocate memory for linked list nodes in heap
head=(struct node*)malloc(sizeof(struct node));
read(head);
traversal(head);
}
The contents of the file is
3
5
6
1
3
The output gives infinite number of lines with not the correct values
Without getting into the implementation of read(), head will remain the same since read() is not modifying it but a copy. You're also nullifying the allocated memory which result in memory leaks.
Since there is no point in allocating head outside read(), I suggest you define it inside to make things more clean, and then return it. Something of this sort:
struct node *read_file() {
FILE *file;
int val;
struct node *prv = NULL;
struct node *head = (struct node *)calloc(1, sizeof(struct node));;
if (head == NULL) {
return NULL;
}
file = fopen("list.txt", "r");
if (fscanf(file, "%d", &val) != EOF) {
head->data = val;
prv = head;
}
while(fscanf(file, "%d", &val) != EOF){
struct node *curr = (struct node *)calloc(1, sizeof(struct node));;
curr->data = val;
if (prv)
prv->next = curr;
prv = curr;
}
fclose(file);
return head;
}
int main(){
struct node *head = read_file();
traversal(head);
}
Don't forget to free the nodes at the end.
I'm new to C and this language is confusing me a bit.
I keep getting a segmentation fault 11 when running my quite simple linked list code:
struct node{
int val;
struct node *next;
};
struct node *init(){
struct node *l = NULL;
return l;
}
struct node *newNode(int val){
struct node* n = init();
n = (struct node*) malloc(sizeof(struct node));
n->val = val;
n->next=NULL;
return n;
}
void append(struct node* h, int val){
struct node *temp;
temp = h;
int i = 0;
while(temp->next != NULL){
temp = temp->next;
i++;
}
printf("TestAppend");
temp= newNode(val);
}
int main(){
struct node* l = init();
printf("Test1\n");
append(l, 15);
printf("Test2\n");
struct node* temp = init();
temp = l;
}
can someone please explain why?
Thanks :)
Try to change init function to:
struct node *init()
{
void* p = malloc(sizeof(struct node));
return (struct node*)p;
}
Edit:
and free it at the end! – Woodrow Barlow
The segmentation fault is because your code is pointing to NULL.
If you replace calls to init() with simple NULL (which is what it is), you will see for yourself that append tries to use NULL->next.
In append, you should check for 'temp!=NULL' first to avoid the seg fault. Also you are declaring an unnecesary local variable which you are not using at all.
I'm new to C and I just started learning how to use pointers. I'm trying to create a function (r) that adds to a bst depending on if the parameter (int n) is greater than the root nodes value. However, I keep getting segmentation fault (core dumped) after running the following code. How do I fix it so that it can run normally without error.
struct node {
int data;
struct node *left;
struct node *right;
}node;
struct node* newNode(int data){
struct node* node = (struct node*)malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
void r (int n, struct node* root);
int main() {
struct node *root = newNode(1);
printf("%d", root->data);
r(10, root);
return 0;
}
void r(int n, struct node* root){
if(n > root->left->data){
root->right = newNode(n);
printf("New right is: %d\n", root->right->data);
}
else if(n < root->left->data){
int a = root->left->data;
root->left->data = n;
root->right->data = a;
printf("New left is: %d\n", root->left->data);
}
return;
}
In the r function you wrote:
root->left->data
But root->left is equal to NULL. This will cause a segfault because you can't dereference a null pointer.
You can check for validity by doing something like:
// Make sure the left node exists, then do the test after
if (root->left && root->left->data > n)
since doing root->left will cause it to check that it's non-zero (meaning not NULL).
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int value;
struct node* next;
}Node;
Node* createNode(int data);
Node* insertFront(Node* first, Node* newNode);
void printList(Node* first);
void deleteList(Node* first);
int main(int argc, const char **argv)
{
int numItems, ch;
FILE *fp;
fp = fopen(argv[1], "r");
while ((ch = getc(fp)) != EOF)
{
if (ch = '\n') numItems++;
}
fclose(fp);
Node *first = NULL;
Node *newNode;
Node *Next;
int i;
for(i = 1; i <= numItems; i++)
{
newNode = createNode(i);
first = insertFront(first, newNode);
}
printList(first);
deleteList(first);
return 1;
}
Node* createNode(int data)
{
Node *newNode;
newNode = malloc(sizeof(Node));
newNode -> value = data;
newNode -> next = NULL;
return newNode;
}
Node* insertFront(Node* first, Node* newNode)
{
if (newNode == NULL) {
/* handle oom */
}
newNode->next=NULL;
if (first == NULL) {
first = newNode;
}
else {
Node *temp=first;
while(temp->next!=NULL)
{
temp = temp->next;
}
temp->next=newNode;
first = newNode;
}
return first;
}
void printList(Node* first)
{
Node *temp;
temp=first;
printf("elements in linked list are\n");
while(temp!=NULL)
{
printf("%d\n",temp->value);
temp=temp->next;
}
}
void deleteList(Node* first)
{
Node *temp;
temp=first;
first=first->next;
temp->next=NULL;
free(temp);
}
Tried running with gdb and this is what I got, first real experience trying to make a linked list.
Program received signal SIGSEGV, Segmentation fault.
_IO_getc (fp=0x0) at getc.c:40
40 _IO_acquire_lock (fp);
I'm not sure what I'm doing wrong here? Thanks for any tips in advance.
You did not initialize numItems to zero. As unitialized it can be any number, including e.g. negative ones. Because of this your list is not created, hence pointer first points to NULL. Then the code segfaults in the function deleteList, when it tries to free memory at location NULL.
I'm working on a linked list implementation in C to get the hang of pointers and structs. Here is the basic code for my LL data structure:
struct Node {
void *data;
struct Node *next;
};
struct List {
struct Node *head;
};
void initList(struct List *list) {
list->head = 0;
}
struct Node *addFront(struct List *list, void *data) {
struct Node *newNode;
newNode->data = data;
newNode->next = list->head;
list->head = newNode;
return newNode;
}
Here is the test I run on it in the int main() function:
int main() {
/* test addFront */
double *data1;
double *data2;
*data1 = 10.5;
*data2 = 10.7;
struct List *newList;
initList(newList);
addFront(newList, data1);
printf("%s\n", newList->head->data);
addFront(newList, data2);
printf("%s\n", newList->head->data);
return 0;
}
My problem is that printf is not printing the output. As it stands now, it obviously doesn't print because %s doesn't match the data type, which is double. If I change the string format to %d, it gives me a segmentation fault. If I add a (double) cast, it says that the second argument has type double *, which confuses me because I thought the -> notation dereferenced a pointer.
I'm lost.
You are dereferencing data1 and data2 without assigning memory to them. Try:
double data1 = 10.5;
addFront(newList, &data1);
Alternatively you could do a malloc, although I don't think you should in this case.
Also, when you want to print them, try:
printf("%f\n", *(double *)newList->head->data);
You are not allocating memory for your double pointers data1 and data2.
Looks like, actually, you're not allocating memory for nearly any of your pointers.
All a pointer does by itself is reference an address in memory. It does not allocate the memory necessary to support the referenced structure or variable.
If you have
double *data1; // or any other kind of pointer
you need something like
data1 = (double *) malloc(sizeof(double));
THEN you can dereference all you like, eg
*data1 = 12.34;
But without that, your referencing a pointer to the Black Hole of Calcutta.
In addition to the 2 printf("%f") there are 4 malloc's missing:
I marked the changed lines with ###:
#include "stdlib.h"
#include "stdio.h"
struct Node {
void *data;
struct Node *next;
};
struct List {
struct Node *head;
};
void initList(struct List *list) {
list->head = 0;
}
struct Node *addFront(struct List *list, void *data) {
struct Node *newNode = malloc(sizeof(struct Node)); //###
newNode->data = data;
newNode->next = list->head;
list->head = newNode;
return newNode;
}
int main() {
/* test addFront */
double *data1 = malloc(sizeof(double)); //###
double *data2 = malloc(sizeof(double)); //###
*data1 = 10.5;
*data2 = 10.7;
struct List *newList = malloc(sizeof(struct List)); //###
initList(newList);
addFront(newList, data1);
printf("%f\n", *(double*)newList->head->data);//###
addFront(newList, data2);
printf("%f\n", *(double*)newList->head->data);//###
// TODO: free()'s //###
return 0;
}
What have you done to try to deal with the problem?
try using "assert.h" to ensure your assertions are right, or if statements with puts/exit.
In particular, if it doesn't print something, clearly what your are printing is not what you want to print, so somewhere along the lines, an assertion must fail, and your mind will "click" where you missed a step.
The reason I can't do this immediatly is because I am not you and I do not know what assertions you are making, so it will take me longer to place them than you would.
Also, as pointed above, you are not allocating memory for newNode, and accessing arbitrary memory, which is causing segmentation fault.
There I fixed it.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
struct Node {
void *data;
struct Node *next;
};
struct List {
struct Node *head;
};
void initList(struct List **newList)
{
struct List* tmpList = 0;
assert(newList != 0);
tmpList = (struct List*)malloc(sizeof(struct List*));
assert(tmpList != 0);
tmpList->head = 0;
*newList = tmpList;
}
void addFront(struct List* list, void* data)
{
struct Node* currNode = 0;
struct Node* prevNode = 0;
assert(list != 0);
assert(data != 0);
currNode = list->head;
while (currNode != 0) {
prevNode = currNode;
currNode = currNode->next;
}
if (prevNode == 0) {
list->head = (struct Node*)malloc(sizeof(struct Node));
list->head->data = data;
list->head->next = 0;
} else {
prevNode->next = (struct Node*)malloc(sizeof(struct Node));
prevNode->next->data = data;
prevNode->next->next = 0;
}
}
void test(const struct List *list)
{
const struct Node *iter;
assert(list != 0);
assert(list->head != 0);
iter = list->head;
while (iter != 0) {
assert(iter->data != 0);
printf("%f\n", *((double*)iter->data));
iter = iter->next;
}
}
int main()
{
double* data1 = (double*)malloc(sizeof(double));
double* data2 = (double*)malloc(sizeof(double));
*data1 = 10.5;
*data2 = 10.7;
struct List* newList = 0;
initList(&newList);
assert(newList->head == 0);
puts("pass[0].");
addFront(newList, data1);
assert(newList->head != 0);
assert(newList->head->data == data1);
puts("pass[1].");
addFront(newList, data2);
assert(newList->head != 0);
assert(newList->head->data == data1);
assert(newList->head->next != 0);
assert(newList->head->next->data == data2);
puts("pass[2].");
test(newList);
return 0;
}