Code wont compile - c

I'm trying to use a queue in my program, but it won't compile and I don't know why. The relevant part of the code is as follows.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#ifndef CUSTOMER
#define CUSTOMER
typedef int bool;
int r;
typedef struct{
int arrival;
int leaving;
} Customer;
static const int MAX_LENGTH = 100;
typedef struct{
int head;
int length;
Customer customer[MAX_LENGTH];
} CustomerLine;
void initializeQueue(CustomerLine* queue)
{
(*queue).head = 0;
(*queue).length = 0;
}
bool hasNext(CustomerLine* queue)
{
return (*queue).length > 0;
}
bool isFull(CustomerLine* queue)
{
return (*queue).length == MAX_LENGTH;
}
bool enqueue(CustomerLine* queue, Customer* customer)
{
if(isFull(queue))
return 0;
int index = ((*queue).head + (*queue).length) % MAX_LENGTH;
(*queue).customer[index] = *customer;
(*queue).length++;
return 1;
}
Customer* dequeue(CustomerLine* queue)
{
if(!hasNext(queue))
return 0;
Customer* result = &(*queue).customer[(*queue).head];
(*queue).length--;
(*queue).head = ((*queue).head + 1) % MAX_LENGTH;
return result;
}
The error says "Variably Modified 'customer' at file scope" I am a beginner at programming and just doing this is starting to get beyond my abilities so any help would be very much appreciated.

The line
static const int MAX_LENGTH = 100
is the problem. Replace it with
#define MAX_LENGTH 100
See why here and more explanations here or here or again here.
Furthermore:
You need an #endif after the #ifndef.
You need a main function somewhere.

In C, const means read-only, not constant and usable just like a macro. You cannot use a variable to specify the dimension of an array as you do here:
static const int MAX_LENGTH = 100;
typedef struct{
int head;
int length;
Customer customer[MAX_LENGTH]; /* Wrong. MAX_LENGTH is not a compile time constant. */
} CustomerLine;

Related

C - How to give a name to a struct dynamically

I am trying to change the number that identifies different structures dynamically (being the last digit of the struct name meant to be the same as the i variable).
Here is an example of what I mean:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char * name;
char * job;
int age;
};
int main () {
time_t t;
srand((unsigned) time(&t));
long random = rand() % 20;
for (int i = 0; i != (random + 1); i++) {
struct Person strcat("Person", i");
}
return 0;
}
I would like that for each i the struct's name changed. So let's say that i = 2. I would like the struct name to be Person2.
Is there any way for me to do this in C?
No, that is not possible. identifiers in C don't change at run-time. In fact, for variables, they generally don't even exist at runtime.
As #VladFromMoscow suggests, what you're probably after is an array of struct Person's, e.g.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char * name;
char * job;
int age;
};
#define MAX_PERSON_NAME_LENGTH 50
#define MAX_NUM_PERSONS 20
int main () {
time_t t;
srand((unsigned) time(&t));
long random = rand() % MAX_NUM_PERSONS;
struct Person persons[random];
for (int i = 0; i != (random + 1); i++) {
persons[i].name = malloc(MAX_PERSON_NAME_LENGTH + 1);
if (persons[i].name != NULL) {
sprintf(persons[i].name, "The %d'th person", i);
}
else {
perror("allocating memory for a person name");
exit(EXIT_FAILURE);
}
}
// do something with persons
return 0;
}
no, but there's no need for such a function anyway. you can achieve what you want by simply creating an array of structs. So, you will access them by doing Person[0], Person[1] etc.. instead of creating 1 different name for each structure

Segmentation fault on separate chaining hashtable

So i implemented a hashtable with separate chaining for a struct called Objective, so that i could perform some operations on said Objectives. Currently i have this:
Hashtable.h:
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/*Using separate chaining to store the obejctives*/
typedef struct Objective{
char name [8000];
unsigned long id, duration, deps [9000];
int hasDeps;
}*pObjective;
typedef struct nodehash{ /*Node of list*/
pObjective obj;
struct nodehash*next;
}*link;
void Init(int M);
int search(unsigned long id);
void insert(pObjective o);
void delete(unsigned long id);
link insertBegin(link h, pObjective obj);
int searchList(link h, unsigned long id);
link removeList(link h, unsigned long id);
pObjective searchObj(unsigned long id);
pObjective searchObjAux(link h, unsigned long id);
#endif
Objectives.c:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "OBJECTIVES.h"
/*Checks if all inserted dependencies already exist*/
int existDeps(unsigned long dep[9000]){
int i, count = 0;
for(i = 0; i < 9000; i++){
if(search(dep[i]) != 0)
count++;
}
return count;
}
/ *Adds objective with dependencies*/
void addObj(unsigned long id, char name [8000], unsigned long duration,
unsigned long dep[9000]){
int i;
pObjective obj = malloc(sizeof(pObjective));
obj->id = id;
obj->duration = duration;
obj->hasDeps = 1;
strcpy(name, obj->name);
for(i = 0; i < 9000; i++){
obj->deps[i] = dep[i];
}
if(search(id) != 0)
printf("id already exists\n");
else if(existDeps(dep) != 0)
printf("no such task\n");
else
insert(obj);
free(obj);
}
/*Adds objective with no dependencies*/
void addNoDeps(unsigned long id, char name [8000], unsigned long
duration){
pObjective obj = malloc(sizeof(pObjective));
obj->id = id;
obj->duration = duration;
obj->hasDeps = 1;
strcpy(name, obj->name);
if(search(id) != 0)
printf("id already exists\n");
else
insert(obj);
free(obj);
}
/*Removes objective with no dependencies*/
void removeObj(unsigned long id){
int res = search(id);
pObjective obj = searchObj(id);
if(res == 0)
printf("no such task\n");
else if(obj->hasDeps == 1)
printf("task with dependencies\n");
else
delete(id);
}
Objectives.h:
#ifndef OBJECTIVES_H
#define OBJECTIVES_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "HASHTABLE.h"
/*Functions to work with objectives*/
int existDeps(unsigned long dep[9000]);
void addObj(unsigned long id, char name [8000], unsigned long duration,
unsigned long dep[9000]);
void addNoDeps(unsigned long id, char name [8000], unsigned long
duration);
void removeObj(unsigned long id);
#endif
Hashtable.c:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "HASHTABLE.h"
#define hash(A,B) (A%B) /*Hash function*/
static link *heads;
static int M;
/*Initiates hashtable with size m*/
void Init(int m){
int i;
M = m;
heads = (link*)malloc(M*sizeof(link));
for(i = 0; i < M; i++)
heads[i] = NULL;
}
/*Searches objective with said id*/
int search(unsigned long id){
int i = hash(id, M);
return searchList(heads[i], id);
}
/*Inserts objective into hashtable*/
void insert(pObjective o){
int i = hash(o->id, M);
heads[i] = insertBegin(heads[i], o);
}
/*Deletes objective using it's id*/
void delete(unsigned long id){
int i = hash(id, M);
heads[i] = removeList(heads[i], id);
}
/*Returns objective with said id*/
pObjective searchObj(unsigned long id){
int i = hash(id, M);
return searchObjAux(heads[i], id);
}
/*Inserts objective into list*/
link insertBegin(link h, pObjective obj){
link new = (link)malloc(sizeof(struct nodehash));
new->obj = obj;
new->next = h;
return new;
}
/*Searches objective by id in a list*/
int searchList(link h, unsigned long id){
link t;
int count = 0;
for(t = h; t != NULL; t = t->next){
if(t->obj->id == id)
count++;
}
return count++;
}
/*Removes objective from list*/
link removeList(link h, unsigned long id){
link t, x, z;
for(t = h; t != NULL; t = t->next){
if(t->next->obj->id == id)
x = t;
}
z = x->next;
x->next = z->next;
free(z);
return h;
}
/*Returns objetive from said id from list*/
pObjective searchObjAux(link h, unsigned long id){
link t, x;
for(t = h; t != NULL; t = t->next){
if(t->obj->id == id)
x = t;
}
return x->obj;
}
I'm quick testing the funcions addObj (adds an objective with dependencies) and addNoDeps (adds an objective with no dependencies) on my main:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "OBJECTIVES.h"
int main(){
unsigned long array [1] = {3};
Init(11);
addNoDeps(1, "tarefa1", 20);
addObj(2, "tarefa2", 20, array);
return 0;
}
But i keep getting segmentation fault(core dumped) and i can't figure out why. Is my implementation wrong? Are the functions wrong? I can't get to the problem, can someone help me?
I can't run your code right now so I can't analyze the core dump, but I believe what is happening is that you are trying to access memory that has already been freed. At the end of addNoDeps, you free the pObjective after putting it into the list. Then, when you addObj after, you search the list and check to make sure that the links object associated with it is not null. Specifically this code:
for(t = h; t != NULL; t = t->next){
if(t->obj->id == id)
count++;
You only check to see that the t (links pointer) is not null, but since you freed the previous object, the t->obj pointer is not pointing to initialized memroy. Therefore trying to access it via t->obj->id is accessing uninitialized memory. If you remove the free(obj) at the end of your addNoDeps and addObj functions you should be fine. You may also want to add checks to make sure that t->obj is not null as well. In general segmentation faults are caused by accessing uninitialized memory, so when debugging check for accessing pointers after a free, double frees, and other things. Also learning to use GDB can help a lot in these situations.

C linked list Process returned 255 (0xFF) execution time 2.144s

I am writing a sequence linked list in C language.
Execution result: Process returned 255 (0xFF) execution time 2.144s
The struct contains array component and use 'typedef' struct as pointer type, what's wrong with it, can anyone help me?
#include <stdio.h>
#define OK 1
#define ERROR 0
#define ERROR_EXIT -1
#define MAXSIZE 30
typedef int Status;
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int len;
}*SQLIST;
Status listInit(SQLIST L)
{
int len = 10;
int i = 0;
for(;i<len;i++)
{
L->data[i] = i; // There is problem here
}
L->len = 10;
return OK;
}
Status listShow(SQLIST L)
{
return OK;
}
int main()
{
SQLIST L;
listInit(L);
printf("%d\n",L->len);
return OK;
}
You should define the struct as:
typedef struct
{
ElemType data[MAXSIZE];
int len;
} SQLIST, *PSQLIST;
Now, you can allocate L in main() like so:
PSQLIST L = malloc(sizeof(SQLIST));
Don't forget to free(L) when you're done with it, and rename all your current instances of SQLIST to PSQLIST.

Why do I keep getting "error: variable has incomplete type 'struct intVec'?

I'm doing an assignment for my data structures class and I have very little experience with C structures and C in general.
This is the .h file that I was given to do the assignment:
#ifndef C101IntVec
#define C101IntVec
typedef struct IntVecNode* IntVec;
static const int intInitCap = 4;
int intTop(IntVec myVec);
int intData(IntVec myVec, int i);
int intSize(IntVec myVec);
int intCapacity(IntVec myVec);
IntVec intMakeEmptyVec(void);
void intVecPush(IntVec myVec, int newE);
void intVecPop(IntVec myVec);
#endif
This is the .c implementation that I've made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "intVec.h"
typedef struct IntVecNode {
int* data;
int sz; // Number of elements that contain data
int capacity; // How much is allocated to the array
} IntVecNode;
typedef struct IntVecNode* IntVec;
//static const int intInitCap = 4;
int intTop(IntVec myVec) {
return *myVec->data;
}
int intData(IntVec myVec, int i) {
return *(myVec->data + i);
}
int intSize(IntVec myVec) {
return myVec->sz;
}
int intCapacity(IntVec myVec) {
return myVec->capacity;
}
IntVec intMakeEmptyVec(void) {
IntVec newVec = malloc(sizeof(struct IntVecNode));
newVec->data = malloc(intInitCap * sizeof(int));
newVec->sz = 0;
newVec->capacity = intInitCap;
return newVec;
}
void intVecPush(IntVec myVec, int newE) {
if (myVec->sz >= myVec->capacity) {
int newCap = myVec->capacity * 2;
myVec->data = realloc(myVec->data, newCap * sizeof(int));
} else {
for (int i = 0; i < myVec->capacity; i++) {
*(myVec->data + i) = *(myVec->data + i + 1);
}
myVec->data = &newE;
}
myVec->sz++;
}
void intVecPop(IntVec myVec) {
for (int i = 0; i < myVec->capacity; i++) {
*(myVec->data - i) = *(myVec->data - i + 1);
}
myVec->sz--;
}
This is the test file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "intVec.c"
int main() {
struct IntVec v;
v.intVecPush(v,0);
return 0;
}
Every time I run the test file, I get the error:
test.c:7:16: error: variable has incomplete type 'struct IntVec'
struct IntVec v;
^
test.c:7:9: note: forward declaration of 'struct IntVec'
struct IntVec v;
^
1 error generated.
I've tried changing the #include "intVec.c" to "intVec.h" in the test file, however that produces the same error. What would I need to change in order to not get this error?
There is no structure definition struct IntVec.
So the compiler is unable to define the object v
struct IntVec v;
I think you mean
IntVec v;
And this call
v.intVecPush(v,0);
is invalid and does not make sense. I think there should be something like
IntVec v = intMakeEmptyVec();
intVecPush(v,0);
instead of
struct IntVec v;
v.intVecPush(v,0);
Also it is a bad idea to include the whole module in another module. You should place the structure definition in the header and include this header in the compilation unit with main.
That is move these definitions
typedef struct IntVecNode {
int* data;
int sz; // Number of elements that contain data
int capacity; // How much is allocated to the array
} IntVecNode;
typedef struct IntVecNode* IntVec;
in the header.

Conflicting types for error

I'm working on a Priority queue with an array implementation. Everything seems to work fine but I get this error: conflicting types for 'remove'
I've declared the function in its header file, I've included the header file but the compiler stil complains. I think the problem resides somewhere else.
Here is pqueue.h:
#ifndef PQUEUE_H
#define PQUEUE_H
//---------------
#define HIGHP 0
#define MEDP 1
#define LOWP 2
#define MAXEL 10
#include <stddef.h>
typedef struct message {
char data[100];
int priority;
} message;
typedef struct pQueue {
struct message messages[10];
int rear;
int front;
int size;
} pQueue;
void initPQueue(pQueue *pq);
void add(pQueue *pq, char *data, int pri);
char* remove(struct pQueue *pq); // Error: conflicting types for: 'remove'
int isEmpty(pQueue *pq);
#endif
pqueue.c:
#include "pqueue.h"
#include <string.h>
void initPQueue(pQueue *pq) {
pq->front = 0;
pq->rear = 0;
pq->size = 0;
}
void add(pQueue *pq, char *data, int pri) {
if (pq->size > MAXEL) {
return; // NOTE: data is lost
}
message m;
strcpy(m.data, data);
m.priority = pri;
if (isEmpty(pq)) {
pq->messages[pq->rear] = m;
pq->rear = (pq->rear % (MAXEL - 1)) + 1;
return; // done
}
/**TODO: NEEDS REPAIR**/
int i = 0;
int j = 0;
for (; i < pq->rear; i = (i % (MAXEL - 1)) + 1) {
if (m.priority > pq->messages[i].priority) {
// found element with higher or equal priority
for (j = pq->rear - 1; j >= i; j = (j % (MAXEL - 1)) - 1) {
pq->messages[j] = pq->messages[j - 1];
}
break;
}
}
pq->messages[i] = m;
/****/
pq->size++;
}
char* remove(struct pQueue *pq) {
if (isEmpty(pq)) {
return NULL ;
}
pq->size--;
return pq->messages[pq->front].data;
}
int isEmpty(pQueue *pq) {
if (!pq->size)
return 1;
return 0;
}
Any thoughts?
int remove(const char *path) is a standard function. You need to choose a different name for yours.
To echo what everyone else has said, there is a standard function. But to add to this, in C, you should always prefix your functions with the name of your library and of the type that it operates on to avoid these sorts of issues. For example, it would be better to name your function something like:
mylibrary_pqueue_remove
This would avoid naming clashes with the standard library and with other peoples' code.
remove is a reserved identifier, you can't use it in your program, as long as you include <stdio.h>.
7.21.4.1 The remove function
#include <stdio.h>
int remove(const char *filename);
The remove function causes the file whose name is the string pointed to by
filename to be no longer accessible by that name. A subsequent attempt
to open that file using that name will fail, unless it is created
anew. If the file is open, the behavior of the remove function is
implementation-defined.

Resources