Getting a segmentation fault for the following:
/*
*
* Linked lists and an editor buffer
*/
/* A doubly-linked node structure.
*/
struct node {
char data;
struct node*next;
struct node*prev;
};
/* Your buffer structure ought to include at least two things:
* (1) Some form of a linked list using your node structure;
* (2) A pointer to of the of the nodes in your list to represent the current
* insertion point.
*/
struct buffer {
struct node*insert; //pointer for the buffer where we add or delete an element
struct node*front;
struct node*back;
int size;
};
/* A structure that is used to represent the buffer contents as two strings:
* - left: the string to the left of the insertion mark;
* - right: the string to the right of the insertion mark.
*
* You may not change the definition of this structure.
*/
struct buffer_contents {
// The contents of the buffer to the left of the insert mark.
char *left;
// The contents of the buffer to the right of the insert mark.
char *right;
};
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "comp211.h"
#include "hw9.h"
//ASSERT
//need to have assert at the beginning and the end of each function
//1.to check the the buffer is a valid buffer -> linear
//2. to make sure the after we do something to the buffer that it is still a valid buffer
bool buf_ok(struct buffer *buf){
if (buf->front==NULL && buf->back==NULL){
return true; //if both the front and back are null then it is linear
}
struct node *slow=buf->front;
struct node *fast=buf->front;
while (fast->next !=NULL && fast->next->next != NULL){ //checks if the spot after fast or two spots after fast is not pointing to NULL so that we dont get a seg. fault if fast tries to move after the first NULL
slow=slow->next; //increment slow to the next node
fast= fast->next->next; //increment fast to teh next node
if (slow==fast){ //if slow and fast are at same node then slow has caught up to fast and the linked list is not linear
return false; //not linear
}
}
return true; //else it is linear
}
struct buffer *empty(void) {
struct buffer *buf=malloc(sizeof(struct buffer));
//create a the buffer using dummy head nodes -> this will help in the future so we dont get errors if we try to point to "nothing"
buf->size=0;
buf->front=malloc(sizeof(struct node));
buf->front->prev=NULL; //nothing will be before the head
buf->back=malloc(sizeof(struct node));
buf->back->next=NULL; //back is the last thing in the list so nothing will follow it
//want front and back to esseintly point to eachother
buf->front->next= buf->back; //since the list only has dummy head nodes and no real content front has to point to back since there is nothing inbetween
buf->back->prev= buf->front; //the link right behind back is front..nothing inbetween because the list is empty
buf->front->data='\0'; //need to start off empty value
buf->back->data='\0'; //need an empty value
buf->insert= buf->back; //have insert point to back since we will insert the first character at the end of the list
return buf;
assert(buf_ok(buf));
}
/* insert(buf, c) inserts c to the left of the insertion point of buf. After
* the insertion, the insert mark is to the right of c.
*/
void insert(struct buffer *buf, char c) {
assert(buf_ok(buf));
struct node *new=malloc(sizeof(struct node));
new->data=c; //insert character
new->next=buf->insert; //assigning the new nodes pointer to insert since insert will be "pushed"" to the right
new->prev=buf->insert->prev; //the previous pointer of new will now point to what the previous pointer of insert use to point to
buf->insert->prev->next=new; //the node that use to point to insert will now point to the new node
buf->insert->prev=new; //inserts previous pointer will now point to new
buf->size++; //increment the size since a new node has been added
assert(buf_ok(buf));
}
/* delete_left(buf) deletes the character to the left of the insert mark. If
* there is no character to the left of the insert mark, this function has no
* effect.
*/
void delete_left(struct buffer *buf) {
assert(buf_ok(buf));
struct node *temp= buf->insert->prev; //a temporary holder for the element we are going to delete
buf->insert->prev= buf->insert->prev->prev; //we need insert to point to the node before the one we are going to delete since the element it currently points to will be gone
temp->prev->next=temp->next; //need to reassign the next pointer of the node before the node being deleted
free(temp);
buf->size--;
assert(buf_ok(buf));
}
/* delete_right(buf) deletes the character to the right of the insert mark. If
* there is no character to the right of the insert mark, this function has no
* effect.
*/
void delete_right(struct buffer *buf) {
assert(buf_ok(buf));
buf->insert= buf->insert->next; //moving the insert point to the right of the node we want to delete and then we are going to esseintly delete left.
struct node *temp= buf->insert->prev;// the node we now want to delete is to the left of insert
buf->insert->prev=buf->insert->prev->prev;//we need insert to point to the node before the one we are going to delete since the element it currently points to will be gone
temp->prev->next=temp->next; //need to reassign the next pointer of the node before the node being deleted
free(temp);
buf->size--;
assert(buf_ok(buf));
}
/* move_left(buf) moves the insert mark one character to the left. If there is
* no character to the left of the insert mark, this functdion has no effect.
*/
void move_left(struct buffer *buf) {
if (buf->insert->prev != buf->front){
buf->insert= buf->insert->prev;
}
assert(buf_ok(buf));
}
/* move_right(buf) moves the insert mark one character to the right. If there
* is no character to the right of the insert mark, this functdion has no
* effect.
*/
void move_right(struct buffer *buf) {
if(buf->insert != buf->back){
buf->insert= buf->insert->next;
}
assert(buf_ok(buf));
}
/* set(buf, n) sets the insert mark so that it is to the left of the n-th
* character. Characters are 0-indexed, so set(buf, 0) sets the insert mark to
* the beginning of the buffer. n may be equal to the length of the buffer; in
* this case, the insert mark is set to the right of the last character.
*
* Pre-condition: 0 <= n <= len(buf).
*/
void set(struct buffer *buf, int n) {
//if n is less than the first index or bigger than the last then just return since it is outof bounds so insert should just stay where it currently is
if(n<0||n > buf->size){
return;
}
//place the insert mark at the firt index
buf->insert= buf->front->next;
//if i is equal to zero or less then the nth character
for (int i=0; i<n; i++){
buf->insert=buf->insert->next; //moving insert foward
} //i is going to be starting at 0 where insert is and then go through the list until it is less than n and then we will place the insert there since the insert has to be placed to the left of the nth character
for(int i=0; i==n; i++){
n=buf->size;
buf->insert= buf->insert->next; //if n is the lenght of buf then the insert needs to be to teh right of n.
}
assert(buf_ok(buf));
}
/* contents(buf) = c, where c->left is the string to the left of the insert
* mark and c->right is the string to the right of the insert mark.
*/
struct buffer_contents *contents(struct buffer *buf) {
assert(buf_ok(buf));
/* calloc initializes memory to 0 */
//going to use variable i to count the size of the list until we reach insert mark
struct buffer_contents* cnt = calloc(buf->size, sizeof(struct buffer_contents));
struct node *temp= malloc(sizeof(struct node));
temp=buf->front->next; //starting at the beingnning of the buffer...->next because we dont want to include the dummy head node
int sizeL=0;
int sizeR=0;
while(temp != buf-> insert){
temp = temp -> next;
sizeL++;
}
while(temp != NULL){
temp=buf->insert->next;
temp = temp -> next;
sizeR++;
}
cnt->left = calloc(sizeL, sizeof(char)); //sizeL is size left of insert
cnt->right = calloc(sizeR, sizeof(char)); //sizeR is the size of the list from insert til the back
//left side up until insertion point
while (temp != buf-> insert){ //up until we reach the insert mark
temp=buf->front->next;
cnt->left=&temp->data;//put all the values to the left of insert into this new string
temp= temp->next;
}
while(temp!=buf->insert->prev && temp!=buf->back){ //right side inlcuding insertion point
temp=buf->insert;
cnt->right=&temp->data;
temp=temp->next;
}
return cnt;
assert(buf_ok(buf));
}