Member reference type issue - c

Hi everyone I'm having a problem with my code and I really don't know how to fix it.
It's telling me that member reference type 'Word'(aka 'struct dict_word *') is not a structure or a union.
I'm trying to change my struct dict_word to word as as you can see on my typedef but when I do it it's giving me that error.
Please have a look at my code I would really appreciate if you could explain that to me.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dict_word *word;
typedef struct node *Node;
typedef struct double_linked_list *DLL;
struct dict_word
{
char words[100];
int year[10];
char eng_synonyms[100];
char heb_synonyms[100];
};
struct node
{
word data;
Node *next;
Node *previous;
};
struct double_linked_list
{
Node *head;
Node *last;
};
int SpliString(struct dict_word* entry, const char *str) // Here is where I'm trying to change struct dict_node to word
{
long sz,j,k;
int yearIndex;
char *buffer;
char *endOfYears;
char *endOfYear;
char *endOfDefinition;
char *endOfWord = strstr(str, "_#_");
//Sets the first num bytes of the block of memory pointed by ptr
//to the specified value (related as an unsigned char)
memset(entry, 0, sizeof(struct dict_word));
if (endOfWord)
{
sz = endOfWord - str;
strncpy(entry->words, str, sz);
endOfYears = strstr(endOfWord+3, "_#_");
if (endOfYears)
{
sz = endOfYears - (endOfWord+3);
buffer = endOfWord+3;
yearIndex = 0;
j = 0;
while(yearIndex<10 && buffer+j<endOfYears)
{
entry->year[yearIndex] = atoi(buffer+j);
// check year for negative...
if (entry->year[yearIndex]<=0)
return 0;
// Locating substring
endOfYear = strchr(buffer+j, '_');
if (endOfYear)
{
j = endOfYear - buffer;
j++;
yearIndex++;
}
else
{
break;
}
}
endOfDefinition = strstr(endOfYears+3, "_#_");
if (endOfDefinition)
{
sz = endOfDefinition - (endOfYears+3);
k = 0;
for(j=0; j<sz; j++)
{
if (endOfYears[j+3]==',') //Q11: what's j+3?
//A11: skips _#_
{
entry->eng_synonyms[k] = ' ';
k++;
}
else if (endOfYears[j+3]>='a' && endOfYears[j+3]<='z')
{
entry->eng_synonyms[k] = endOfYears[j+3];
k++;
}
else if (endOfYears[j+3]!='_')
{
return 0;
}
}
k = 0;
sz = (str+strlen(str)) - (endOfDefinition+3);
for(j=0; j<sz; j++)
{
if (endOfDefinition[j+3]==',')
{
entry->heb_synonyms[k] = ' ';
k++;
}
else if (endOfDefinition[j+3]>='A' && endOfDefinition[j+3]<='Z')
{
entry->heb_synonyms[k] = endOfDefinition[j+3];
k++;
}
else if (endOfDefinition[j+3]!='_')
{
return 0;
}
}
}
// check for legality
for(j=0;j<(int)strlen(entry->words);j++)
{
if (entry->words[j]<'a' || entry->words[j]>'z')
return 0;
}
return 1;
}
}
return 0;
}

Related

CS50 "Speller": Problem with dictionary file

I'm working on CS59 Week 5's "Speller" assignment. Currently, I'm trying to write the unload function with a test dictionary file on my desktop. But for some reason, line 91 (while(!feof(dictionary))) is returning an error:
"request for member '_flag' in something not a structure or a union"
I'm working from a new computer. My previous computer did not return this error. Can someone please explain what's going on here and how I can fix it? Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
unsigned int HASH_MAX = 50;
unsigned int LENGTH = 20;
unsigned int hash (const char *word);
bool load(char *dictionary);
bool check (char *word);
bool unload (void);
void print (void);
typedef struct _node
{
char *word[20];
struct _node *next;
} node;
node *HASH_TABLE[50];
int main(int argc, char *argv[])
{
FILE *dictionary = fopen("C:/Users/aaron/Desktop/Dictionary.txt", "r");
if(!dictionary)
{
printf("FILE NOT FOUND\n");
return 1;
}
if (load(dictionary))
{
// print "LIST (number): {(name, address), ...}\n
print();
}
int lois = hash("Lois");
printf("\n%s\n", HASH_TABLE[lois]->word);
if (check("StEwIe"))
{
printf("STEWIE found\n");
}
else if (!check("StEwIe"))
{
printf("STEWIE not found\n");
}
if (check("Tron"))
{
printf("TRON found\n");
}
else if (!check("Tron"))
{
printf("TRON not found\n");
}
if (unload())
{
print();
}
}
unsigned int hash(const char *word) // hash code function (FIND A BETTER ALGORITHM)
{
char word_conv[LENGTH + 1]; // store converted word for uniform key
unsigned int code = 0; // hash code
for (int i = 0; i < strlen(word); i++) // set all letters in the word to lower case
{
word_conv[i] = tolower(word[i]);
}
for (int j = 0; j < strlen(word_conv); j++) // for all letters in converted word, add ascii value to code and multiply by 3
{
code += word_conv[j];
code *= 3;
}
code = code % HASH_MAX; // set code to remainder of current code divided by maximum hash table size
return code;
}
bool load (char *dictionary)
{
char word[LENGTH+1];
while(!feof(dictionary))
{
fscanf(dictionary, "%s", word);
node *new_n = malloc(sizeof(node));
strcpy(new_n->word, word);
new_n->next = NULL;
unsigned int code = hash(word);
if (HASH_TABLE[code] == NULL)
{
HASH_TABLE[code] = new_n;
}
else if (HASH_TABLE[code] != NULL)
{
node *trav = HASH_TABLE[code];
while (trav->next != NULL)
{
trav = trav->next;
}
if (trav->next == NULL)
{
trav->next = new_n;
}
}
}
return true;
}
bool check (char *word)
{
unsigned int code = hash(word);
node *check = malloc(sizeof(node));
check = HASH_TABLE[code];
while (check != NULL)
{
if (strcasecmp(check->word, word) == 0)
return true;
}
if (check == NULL)
return false;
}
bool unload (void)
{
for (int i = 0; i < HASH_MAX; i++)
{
while (strcmp(HASH_TABLE[i]->word, "FREE" != 0)
{
node *curr = HASH_TABLE[i];
node *prev = NULL;
while (curr != NULL)
{
prev = curr;
curr = curr->next;
}
strcpy(prev->word, "FREE");
}
}
return true; // freed successfully
}
void print (void)
{
for (int i = 0; i < HASH_MAX; i++)
{
node *check = HASH_TABLE[i];
printf("LIST %02d: {", i);
while (check != NULL)
{
printf("%s, ", check->word);
check = check->next;
}
printf("}\n");
}
}

Getting a segmentation fault error on an Open Addressing Hash Map?

I'm getting a segmentation fault error somewhere in my insert function. It says that its due to one of the 'strcmp' comparisons but i cant find the issue after looking at all of them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define INITIAL_CAPACITY 8
typedef struct node
{
unsigned int val;
char *key;
bool del;
} Node;
typedef Node * NodePtr;
typedef struct hashMap
{
NodePtr array;
size_t capacity;
size_t size;
} HashMap;
typedef HashMap * HMPtr;
//|-------------------------
HMPtr create();
void insert(HMPtr map, char *str);
//y
void resize_insert(HMPtr map, char *str);
//y
void print(HMPtr map);
void destroy(HMPtr *mapPtr);
void resize(HMPtr map);
//y
unsigned int hash(char *str);
//y
unsigned int pop(HMPtr map, char *key);
//y
//|-------------------------
int main(void)
{
HMPtr map = create();
insert(map, "Keathan");
insert(map, "Trey");
insert(map, "Noah");
insert(map, "Kleiner");
insert(map, "data");
insert(map, "Matthew");
print(map);
destroy(&map);
return 0;
}
unsigned int pop(HMPtr map, char *str)
{
unsigned int val = hash(str);
size_t h = (size_t)val;
size_t index = h % map->capacity;
for(size_t i = 0; map->array[index].key && strcmp(str, map->array[index].key);index = (h + ((++i) + i*i)/2)%map->capacity);
if (map->array[index].key)
{
map->array[index].del = true;
return map->array[index].val;
}
return 0;
}
unsigned int hash(char *str)
{
unsigned int out = 0;
unsigned int base = 31;
unsigned int factor = 1;
for (size_t i = 0; str[i] != 0; ++i)
{
out += (unsigned int)str[i] * factor;
factor *= base;
}
return out;
}
void resize(HMPtr map)
{
NodePtr old = map->array;
size_t old_capacity = map->capacity;
map->capacity = old_capacity * 2;
map->array = calloc(map->capacity, sizeof(Node));
for(size_t i = 0; i < old_capacity; ++i)
{
if(old[i].key)
{
if(old[i].del)
free(old[i].key);
else
resize_insert(map, old[i].key);
}
}
free(old);
}
void resize_insert(HMPtr map, char *str)
{
unsigned int val = hash(str);
size_t h = (size_t)val;
size_t index = h % map->capacity;
for (size_t i = 0; map->array[index].key; index = (h + ((++i) + i*i)/2)%map->capacity);
map->array[index].key = str;
map->array[index].val = val;
++(map->size);
}
void insert(HMPtr map, char *str)
{
unsigned int val = hash(str);
size_t h = (size_t)val;
size_t index = h % map->capacity;
size_t i;
NodePtr deleted = NULL;
for(i = 0; map->array[index].key && strcmp(str, map->array[index].key);index = (h + ((++i) + i*i)/2)%map->capacity)
if(!deleted && map->array[index].del)
{
deleted = map->array + index;
for(index = (h + ((++i) + i*i)/2)%map->capacity; map->array[index].key && strcmp(str, map->array[index].key); index = (h + ((++i) + i*i)/2)%map->capacity);
break;
}
if (map->array[index].key == NULL)
{
if(deleted)
{
free(deleted->key);
deleted->del = false;
index = deleted - map->array;
}
else if (++(map->size) >= 0.7*map->capacity)
{
resize(map);
index = h % map->capacity;
for (i = 0; map->array[index].key; index = (h + ((++i) + i*i)/2)%map->capacity);
}
map->array[index].key = calloc(strlen(str)+1, sizeof(char));
strcpy(map->array[index].key, str);
}
else
map->array[index].val = val;
}
HMPtr create()
{
HMPtr newList = malloc(sizeof(HashMap));
newList->size = 0;
newList->capacity = INITIAL_CAPACITY;
newList->array = calloc(newList->capacity, sizeof(NodePtr));
return newList;
}
void destroy(HMPtr *mapPtr)
{
free((*mapPtr)->array);
free(*mapPtr);
*mapPtr = NULL;
}
void print(HMPtr map)
{
for (size_t i = 0; i < map->capacity; ++i)
printf("%s;%u\n", map->array[i].key, map->array[i].val);
}
This is the Error i recieved after running on gdb
'''
Program received signal SIGSEGV, Segmentation fault.
__strcmp_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S:30
30 ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S: No such file or
directory.
'''
If anyone could spot the issue then that would help a lot. Thanks!
sizeof(nodePtr) is size of pointer you need sizeof(struct Node)
HMPtr create()
{
HMPtr newList = malloc(sizeof(HashMap));
newList->size = 0;
newList->capacity = INITIAL_CAPACITY;
newList->array = calloc(newList->capacity, sizeof(*newList->array));
return newList;
}

C error expected identifer before '(' token in structs

I am trying to change my data in my cacheSets but I am getting this error for some reason. I have a cacheSet global to make things easier for me.
typedef struct cacheLine
{
int valid;
int counter;
int tag;
int block;
};
typedef struct cacheSet
{
int setnum;
int E;
struct cacheLine *lines;
};
void createCache(int E, int S);
void hitormiss(int address,int tag, int offset);
struct cacheSet *sets;
void createCache(int E, int S)
{
sets = malloc(sizeof(sets) * S);
for(int i = 0; i < S; i++)
{
sets->lines = malloc(sizeof(sets->lines) * E);
sets->setnum = i;
sets->E = E;
}
}
This function has all the errors, all the lines that I'm trying to access tags,offsets and counter are throwing all the errors. So everyone line that has (lines + i) is throwing an error. I might be confusing my self because I'm trying to access data in a struct that's in a struct.
void hitormiss(int address,int tag, int offset)
{
for(int i = 0; i < sets->E; i++)
{
/*if tag == to the address tag then its a hit*/
if(sets->(lines + i)->tag == tag)
{
printf("%d H\n",address);
sets->(lines + i)->counter++;
}
/*if theres a miss*/
else if(sets->(lines + i)->tag != tag)
{
printf("%d M\n",address);
sets->(lines + i)->tag = tag;
sets->(lines + i)->block = offset;
sets->(lines + i)->counter = 0;
}
/*cold miss*/
else
{
printf("%d M\n",address);
sets->(lines + i)->tag = tag;
sets->(lines + i)->block = offset;
sets->(lines + i)->counter = 0;
}
}
}

VS17 not initializing pointer

My problem is that this code is not working in VS 2017 while in CLion it works.
VS says:
Severity Code Description Project File Line Suppression State
Error (active) E0144
a value of type void * cannot be used to initialize an entity of type queue_t*
therefor the program is not allocating the memory.
Further every pointer like the example above is not working.
Does somebody here know why that is the case, why VS thinks that this would be a void?
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
struct packet_t {
double d;
int i;
long l;
char *p;
struct queue_t *queue;
};
struct queue_t {
char *name;
int size;
int entries;
double time;
struct packet_t **packets;
int read;
int write;
long lost;
long total;
};
int decision = -1;
int isRunning = 1;
void logError(char message[]) {
printf("ERROR: %s", message);
}
struct queue_t *queue_create(char *name, int size) {
struct queue_t *q = malloc(sizeof(struct queue_t));
if (!q) {
logError("could not allocate memory!\n");
return 0;
}
else {
q->name = name;
q->size = size;
q->entries = 0;
q->read = 0;
q->write = 0;
q->total = 0;
q->lost = 0;
q->packets = malloc(size * sizeof(struct packet_t *));
if (!q->packets) {
logError("could not allocate memory!\n");
free(q);
return 0;
}
struct packet_t **current;
for (int i = 0; i < size; i++) {
current = q->packets + i;
*current = NULL;
}
}
return q;
}
int packet_destroy(struct packet_t *packet) {
//TODO test if deleted ?
if (packet) {
free(packet);
return 1;
}
return 0;
}
long queue_store(struct queue_t *queue, struct packet_t *packet) {
if (queue->entries < queue->size) {
packet->queue = queue;
*(queue->packets + queue->write) = packet;
queue->write++;
if (queue->write == queue->size) {
queue->write = 0;
}
queue->total++;
queue->entries++;
return queue->total;
}
//cant save packet ->destroy
packet_destroy(packet);
queue->lost++;
return 0;
}
struct packet_t *queue_retrieve(struct queue_t *queue) {
if (queue->entries == 0) return NULL;
struct packet_t **current = queue->packets + queue->read;
struct packet_t *packet = *current;
*current = NULL;
if (packet->queue) {
packet->queue = NULL;
}
queue->entries--;
queue->read++;
if (queue->read == queue->size) {
queue->read = 0;
}
return packet;
}
struct packet_t *packet_create(int i, double d, long l, char *p) {
struct packet_t *new = malloc(sizeof(struct packet_t));
if (new) {
new->i = i;
new->d = d;
new->l = l;
new->p = p;
}
else {
logError("failed to allocate memory");
}
return new;
}
int queue_destroy(struct queue_t *queue) {
if (!queue) {
logError("could not find queue!");
return 0;
}
struct packet_t *p;
for (int i = 0; i < queue->size; i++) {
p = *(queue->packets + i);
packet_destroy(p);
}
//TODO test if not needed as it's already free'd in packet_destroy
free(queue->packets);
free(queue);
return 0;
}
long test_queue(int val) {
int sum = 0, finalTime = 0;
clock_t startTime, finalTicks;
startTime = clock();
while (finalTime < val) {
struct queue_t *q = queue_create("test", 10);
queue_destroy(
sum++;
finalTicks = (clock() - startTime);
// printf("ticks: %d\n", finalTicks);
finalTime = (int)floor((finalTicks / (double)CLOCKS_PER_SEC));
// printf("time: %d\n", finalTime);
}
printf("Runtime: %d\n seconds", finalTime);
printf("Added and removed %d queues\n", sum);
}
long test_packets(int val) {
int finalTime = 0;
struct queue_t *q = queue_create("test", 10);
clock_t startTime, finalTicks;
startTime = clock();
while (finalTime < val) {
struct packet_t *t = packet_create(finalTime, finalTime + 1, finalTime + 2, NULL);
queue_store(q, t);
packet_destroy(queue_retrieve(q));
finalTicks = (clock() - startTime);
// printf("ticks: %d\n", finalTicks);
finalTime = (int)floor((finalTicks / (double)CLOCKS_PER_SEC));
// printf("time: %d\n", finalTime);
}
printf("Runtime: %d\n", finalTime);
printf("Successfully added %li entries\n", q->total);
printf("Failed to add %li entries\n", q->lost);
queue_destroy(q);
}
void resetDecision() {
decision = -1;
isRunning = 1;
}
void checkDecision() {
while (decision != 0 && decision != 1 && decision != 2) {
printf("Select option:\n (1) Run queue test \n (2) Run packet test \n(0) to cancel \n");
scanf("%d", &decision);
}
if (decision == 0) {
isRunning = 0;
}
else if (decision == 1) {
int val = 0;
while (val <= 0) {
printf("Enter the time to test");
scanf("%d", &val);
}
printf("Running test for %d seconds....\n", val);
test_queue(val);
}
else if (decision == 2) {
int val = 0;
while (val <= 0) {
printf("Enter the time to test");
scanf("%d", &val);
}
printf("Running test for %d seconds....\n", val);
test_packets(val);
}
if (decision != 0)
resetDecision();
}
int main() {
while (isRunning) {
checkDecision();
}
return 0;
}
You are compiling your program as a C++ program. In C++ there is no implicit conversion from the type void * to pointer of other object type.
So you need to write using explicit casting like
struct queue_t *q = ( struct queue_t * )malloc(sizeof(struct queue_t));
Or you should consider your program as indeed a C++ program and use the operator new instead of the C function malloc.

Setting struct value = segfault

#include <stdio.h>
#include <stdlib.h>
#define true 1
struct hashRow {
char *key;
char *value;
};
struct hash_table {
int max;
int number_of_elements;
struct hashRow **elements;
};
int hashstring(const char *s)
{
int key = 0;
while (*s)
key = key * 37 + *s++;
return key;
}
int hash_fun(int key, int try, int max) {
return (key + try) % max;
}
struct hash_table *table;
int hash_insert(struct hashRow *data, struct hash_table *hash_table) {
int try, hash;
if(hash_table->number_of_elements < hash_table->max) {
return 0; // FULL
}
for(try = 0; true; try++) {
int hkey = hashstring(data->key);
hash = hash_fun(hkey, try, hash_table->max);
if(hash_table->elements[hash] == 0) { // empty cell
hash_table->elements[hash] = data;
hash_table->number_of_elements++;
return 1;
}
}
return 0;
}
struct hashRow *hash_retrieve(char *key, struct hash_table *hash_table) {
int try, hash;
for(try = 0; true; try++) {
int hkey = hashstring(key);
hash = hash_fun(hkey, try, hash_table->max);
if(hash_table->elements[hash] == 0) {
return 0; // Nothing found
}
if(hash_table->elements[hash]->key == key) {
return hash_table->elements[hash];
}
}
return 0;
}
int hash_delete(char *key, struct hash_table *hash_table) {
int try, hash;
for(try = 0; true; try++) {
int hkey = hashstring(key);
hash = hash_fun(hkey, try, hash_table->max);
if(hash_table->elements[hash] == 0) {
return 0; // Nothing found
}
if(hash_table->elements[hash]->key == key) {
hash_table->number_of_elements--;
hash_table->elements[hash] = 0;
return 1; // Success
}
}
return 0;
}
void insertsomething()
{
struct hashRow *toInsert;
toInsert = (struct hashRow *)malloc(sizeof(*toInsert));
printf("toInsert declared\n");
char *k = (char*)malloc(sizeof(char*));
char *v = (char*)malloc(sizeof(char*));
k = "sayhello";
v = "hello";
this is where I seem to be having the problem.
toInsert->key = k;
toInsert->value = v;
hash_insert(toInsert, table);
}
int main()
{
printf("calling insertsomething.\n");
insertsomething();
struct hashRow *gotten;
gotten = hash_retrieve("sayhello", table);
printf("test: %s\n", gotten->value);
}
I'm trying to create a hash table, but whenever I try to set a value in the toInsert struct pointer it segfaults. Can someone explain to me what I am doing wrong?
Try this:
void insertsomething()
{
struct hashRow *toInsert;
toInsert = (struct hashRow *)malloc(sizeof(*toInsert));
printf("toInsert declared\n");
/*
char *k = (char*)malloc(sizeof(char*)); // wrong size
char *v = (char*)malloc(sizeof(char*)); // wrong size
k = "sayhello"; // bad assignment
v = "hello"; // bad assignment
*/
toInsert->key = strdup("sayhello");
toInsert->value = strdup("hello");
hash_insert(toInsert, table);
}
Also, I can't spot where you reserve memory for your hash_table. Is it hidden somewhere else??

Resources