Problems with this stack implementation - c

where is the mistake?
My code here:
typedef struct _box
{
char *dados;
struct _box * proximo;
} Box;
typedef struct _pilha
{
Box * topo;
}Stack;
void Push(Stack *p, char * algo)
{
Box *caixa;
if (!p)
{
exit(1);
}
caixa = (Box *) calloc(1, sizeof(Box));
caixa->dados = algo;
caixa->proximo = p->topo;
p->topo = caixa;
}
char * Pop(Stack *p)
{
Box *novo_topo;
char * dados;
if (!p)
{
exit(1);
}
if (p->topo==NULL)
return NULL;
novo_topo = p->topo->proximo;
dados = p->topo->dados;
free(p->topo);
p->topo = novo_topo;
return dados;
}
void StackDestroy(Stack *p)
{
char * c;
if (!p)
{
exit(1);
}
c = NULL;
while ((c = Pop(p)) != NULL)
{
free(c);
}
free(p);
}
int main()
{
int conjunto = 1;
char p[30], * v;
int flag = 0;
Stack *pilha = (Stack *) calloc(1, sizeof(Stack));
FILE* arquivoIN = fopen("L1Q3.in","r");
FILE* arquivoOUT = fopen("L1Q3.out","w");
if (arquivoIN == NULL)
{
printf("Erro na leitura do arquivo!\n\n");
exit(1);
}
fprintf(arquivoOUT,"Conjunto #%d\n",conjunto);
while (fscanf(arquivoIN,"%s", p) != EOF )
{
if (pilha->topo == NULL && flag != 0)
{
conjunto++;
fprintf(arquivoOUT,"\nConjunto #%d\n",conjunto);
}
if(strcmp(p, "return") != 0)
{
Push(pilha, p);
}
else
{
v = Pop(pilha);
if(v != NULL)
{
fprintf(arquivoOUT, "%s\n", v);
}
}
flag = 1;
}
StackDestroy(pilha);
return 0;
}
The Pop function returns the string value read from file.
But is not correct and i don't know why.

You're not allocating any storage for the strings pointed to by dados - you're just re-using one string buffer (p) and passing that around, so all your stack elements just point to this one string.

Related

Deleting the root of a heap with no effect

I have tried to implement functions related to heaps in C and I have stumbled across a problem with my delete heap root function.
When the heap has only one element, the function does not delete anything, even though I explicitly said that the heap becomes NULL if it has only one element.
Below I have posted my code with all the functions that I have created (maybe there is something wrong with the other functions, but it doesn't seem likely to me). The main problem is the deleteRoot function.
#include <stdio.h>
#include <stdlib.h>
typedef struct Heap Heap;
struct Heap
{
Heap *left;
Heap *right;
Heap *parent;
int value;
};
Heap *newHeap(int x)
{
Heap *t = malloc(sizeof(Heap));
t->value = x;
t->left = NULL;
t->right = NULL;
t->parent = NULL;
return t;
}
void printHeap(Heap *h)
{
if(h!=NULL)
{
printf("Value %d (",h->value);
printHeap(h->left);
printf(")");
printf("(");
printHeap(h->right);
printf(")");
}
}
int getHeapMinDepth(Heap *h)
{
if(h == NULL) return 0;
int leftdepth = getHeapMinDepth(h->left);
int rightdepth = getHeapMinDepth(h->right);
int mindepth = (leftdepth < rightdepth) ? leftdepth : rightdepth;
return mindepth + 1;
}
int getHeapMaxDepth(Heap *h)
{
if(h == NULL) return 0;
int leftdepth = getHeapMaxDepth(h->left);
int rightdepth = getHeapMaxDepth(h->right);
int maxdepth = (leftdepth > rightdepth) ? leftdepth : rightdepth;
return maxdepth + 1;
}
void bubbleUp(Heap *h)
{
int aux;
if(h->parent != NULL && h != NULL)
{
if(h->parent->value < h->value)
{
aux = h->value;
h->value = h->parent->value;
h->parent->value = aux;
bubbleUp(h->parent);
}
}
}
void bubbleDown(Heap *h)
{
int aux;
if(h != NULL)
{
if(h->left != NULL && h->left->value > h->value)
{
aux = h->value;
h->value = h->left->value;
h->left->value = aux;
bubbleDown(h->left);
}
else if(h->right != NULL && h->right->value > h->value)
{
aux = h->value;
h->value = h->right->value;
h->right->value = aux;
bubbleDown(h->right);
}
}
}
void addElement(Heap *h ,int x)
{
if(h == NULL) h = newHeap(x);
else if(h->left == NULL)
{
h->left = newHeap(x);
h->left->parent = h;
bubbleUp(h->left);
}
else if(h->right == NULL)
{
h->right = newHeap(x);
h->right->parent = h;
bubbleUp(h->right);
}
else if(getHeapMinDepth(h->left) <= getHeapMinDepth(h->right)) addElement(h->left,x);
else addElement(h->right,x);
}
void deleteRoot(Heap *h)
{
Heap *auxheap = h;
if(h!=NULL && h->left == NULL && h->right == NULL) h = NULL;
else if(h!=NULL)
{
while(auxheap ->left != NULL || auxheap->right != NULL)
{
if(getHeapMaxDepth(auxheap->left) > getHeapMaxDepth(auxheap->right)) auxheap = auxheap->left;
else auxheap = auxheap->right;
}
h->value = auxheap->value;
auxheap->value = -1;
auxheap = auxheap->parent;
if(auxheap->right != NULL && auxheap->right->value == -1) auxheap->right = NULL;
else auxheap->left = NULL;
bubbleDown(h);
}
}
int main()
{
int i;
Heap *h = newHeap(2);
deleteRoot(h);
addElement(h,12);
addElement(h,5);
addElement(h,7);
addElement(h,15);
printHeap(h);
return 0;
}
Thank you in advance!
In order to avoid your call-by-value problem in C, use a pointer to pointer as parameter for your root-deletion function.
void deleteRoot(Heap **h)
{
/* assuming that h is not NULL, which is guaranteed with "&something" */
if((*h)!=NULL && (*h)->left == NULL && (*h)->right == NULL) *h = NULL;
/* ... */
}
int main()
{
int i;
Heap *h = newHeap(2);
deleteRoot(&h);
/* ... */
return 0;
}

Malloc and Realloc crash in C?

i have to do with my friend a program in C for my school.
The problem is, when i would malloc a pointer, it doesn't work, and the application will crashed.
But not in debug mod. In debug mod, it works.
This is a part of my code:
#include <bplus.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LOG "log.txt"
#define LOGIDX "log.idx"
struct event {
time_t nb;
char *username;
int type;
char *message;
};
struct eventlist {
struct event event;
struct eventlist *nextelem;
};
struct eventlist *getEventList(time_t date);
void insert(struct eventlist *list, struct eventlist *event);
struct event getEventFromString(char *str);
char *getLine(FILE *file);
int file_exists(const char *fname);
char *dechiffrer(const char *pChaineChiffree);
int main(void) {
time_t timenow = time(NULL);
struct tm *tm = gmtime(&timenow);
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
time_t time = mktime(tm);
struct eventlist *list = getEventList(time);
return 0;
}
struct eventlist *getEventList(time_t date) {
int end = 0;
FILE *file = NULL;
char str[20];
char *line = NULL;
char *uncode = NULL;
ENTRY e;
IX_DESC faddress;
struct eventlist *list = NULL; // Liste a retourner
struct event *event = NULL; // Contient l'evenement
struct eventlist *templist = NULL; // Contient l'evenement a mettre dans list
// On ouvre / crée le fichier .idx
if (file_exists(LOGIDX))
open_index(LOGIDX, &faddress, 0);
else
make_index(LOGIDX, &faddress, 0);
// On ouvre le fichier de log
if ((file = fopen(LOG, "rb")) != NULL) {
// On met dans e.key le temps
sprintf(str, "%d", (int) date);
strcpy(e.key, str);
if (find_key(&e, &faddress)) { // Si la clé existe
fseek(file, e.recptr, SEEK_SET); // On se positionne
line = getLine(file); // On récupère la ligne
while (!feof(file) && !end) { // Boucle principale
printf("\ngetEventList 1");
if (line != NULL) {
uncode = dechiffrer(line); // On déchiffre la ligne
printf("\ngetEventList 2");
event = (struct event *) malloc(sizeof(struct event *) * 1); // On alloue de la place
printf("\ngetEventList 3");
if (event) {
*event = getEventFromString(uncode); // On la transforme en structure
printf("\ngetEventList 4");
if (event->nb < date + 86400) {
templist = (struct eventlist *) malloc(sizeof(struct eventlist *) * 1);
printf("\ngetEventList 5");
if (templist) {
templist->event = *event;
templist->nextelem = NULL;
printf("\ngetEventList 6");
if (list == NULL)
list = templist;
else
insert(list, templist);
printf("\ngetEventList 7");
line = getLine(file); // On récupère la ligne
printf("\ngetEventList 8");
} else {
list = NULL;
end = 1;
}
} else
end = 1;
} else {
list = NULL;
end = 1;
}
} else
end = 1;
}
} else { // Sinon, on affiche un message
list = NULL;
printf("\nErreur: Clé non trouvée !");
}
fclose(file);
} else {
list = NULL;
printf("\nErreur lors de l'ouverture du fichier !");
}
return list;
}
void insert(struct eventlist *list, struct eventlist *event) {
struct eventlist *temp = list;
struct eventlist *lasttemp = NULL;
printf("\n(%s %s)", temp->event.username, event->event.username);
while (temp->nextelem != NULL && stricmp(temp->event.username, event->event.username)) {
temp = temp->nextelem;
}
lasttemp = temp;
while (temp != NULL && !stricmp(temp->event.username, event->event.username)) {
lasttemp = temp;
temp = temp->nextelem;
}
event->nextelem = temp;
lasttemp->nextelem = event;
}
struct event getEventFromString(char *str) {
struct event event;
event.nb = 0;
event.type = 0;
event.username = NULL;
event.message = NULL;
int time;
int type;
char *username = (char *) malloc(sizeof(char *) * strlen(str));
char *message = (char *) malloc(sizeof(char *) * strlen(str));
if (sscanf(str, "%d %d %s %[^\n]s", &(time), &(type), username, message)) {
event.nb = (time_t) time;
event.type = type;
event.username = username;
event.message = message;
}
return event;
}
char *getLine(FILE *file) {
char *line = NULL;
unsigned char c;
int end = 0;
int ln = 0;
printf("\ngetLine 1");
line = (char *) malloc(sizeof(char *) * 1);
printf("\ngetLine 2");
if (line != NULL) {
while(!feof(file) && !end) {
c = fgetc(file);
if (c != '\n' && c != '\r') {
printf("\nDEBUG: %c %d %s", c, ln, line);
line = (char *) realloc(line, sizeof(char *) * (ln + 2));
if (line != NULL) {
line[ln++] = c;
line[ln] = '\0';
} else
end = 1;
} else
end = 1;
}
line[ln] = '\0';
}
if (line[0] == '\0' || line[1] == '\0')
line = NULL;
return line;
}
int file_exists(const char *fname) {
FILE *file;
int returncode = 0;
if ((file = fopen(fname, "r"))) {
fclose(file);
returncode = 1;
}
return returncode;
}
char *dechiffrer(const char *pChaineChiffree) {
char *dechiff;
unsigned char car;
unsigned int i;
dechiff = malloc(strlen(pChaineChiffree) + 1);
for (i = 0; pChaineChiffree[i] != '\0'; i++) {
car = pChaineChiffree[i];
car = (car & 0x0F) << 4 | (car & 0xF0) >> 4;
// car -= 0x55;
dechiff[i] = car;
}
dechiff[i] = '\0';
return dechiff;
}
I think it's a bufferoverflow, but i don't know where is the problem, and why it's bugged.
The crash occured in this malloc:
printf("\ngetLine 1");
line = (char *) malloc(sizeof(char *) * 1);
printf("\ngetLine 2");
Please help me
Thanks
0ddlyoko
EDIT:
Ok i've found the problem, it was with all my sizeof(XXX *), i've just changed this to sizeof(XXX).
Thanks !

Trouble using push in stack

I'm learning data structures and I have a problem pushing data into my stack. Even though I have used the same push function early in the program it doesn't seem to push characters. The program should transform infix expressions to postfix
When given the number "1+2" it should return "12+", however it only returns "12"
Thanks in advice
bool revisar(char * inf, stack p){
inicializa(&p);
Nodo D;
char pos[MAX];
int i=0;
int j=0;
while(inf[i]!='\0')
{//WHILE
if(inf[i]>='0' && inf[i]<='9')
{
pos[j++]=inf[i++];
}
if(inf[i]=='(')
{
D.caracter=inf[i++];
push(&p,D);
}
if(inf[i]==')')
{
while(top(p).caracter!='(')
{
pos[j++]=pop(&p).caracter;
}
if(top(p).caracter=='(')
pop(&p);
i++;
}
else
{
if(inf[i]=='+'||inf[i]=='-'||inf[i]=='*'||inf[i]=='/')
{
if(empty(p)||top(p).caracter=='(')
{
D.cara
cter=inf[i++];
push(&p,D);
if(empty(p));
printf("NNNNNNOOOOOOOOOOOOOOOOOOOOOO"); **Here it prints that the stack is still empty....
}
else
{
if(menorpre(top(p).caracter,inf[i]))
{
D.caracter=inf[i++];
push(&p,D);
}
else
{
pos[j++]=pop(&p).caracter;
if(!empty(p))
{
if(top(p).caracter!='(')
pos[j++]=pop(&p).caracter;
}
else
{
D.caracter=inf[i++];
push(&p,D);
}
}
}
}
}
}
while(!empty(p)){
printf("ddd");
pos[j++]=pop(&p).caracter;
}
pos[j]='\0';
printf("\n \n");
printf("i=%d,j=%d",i,j);
printf("LA CADENA EN POSFIJO ES: ");
puts(pos);
}
My stack library
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include "pila.h"
void inicializa(stack *p ){
*p = NULL;
}
bool empty(stack p){
if (p==NULL){
return true;
}
else return false;
}
int push(stack * p, Nodo n){
stack nuevo = (stack)malloc(sizeof(Nodo));
if(nuevo == NULL){
return 300;
}
*nuevo = n;
if(empty(*p)){
nuevo->next = NULL;
}
else{
nuevo->next = *p;
*p = nuevo;
}
return 301;
}
Nodo pop(stack * p){
Nodo copy = *(*p);
free(*p);
*p = copy.next;
inicializa(&copy.next);
return copy;
}
Nodo top(stack p){
Nodo copy;
copy = *p;
copy.next = NULL;
return copy;
}
The header file
struct nodo{
char caracter;
int numero;
struct nodo * next;
};
typedef struct nodo Nodo;
typedef Nodo * stack;
void inicializa(stack *p);
bool empty(stack p);
Nodo top(stack p);
Nodo pop(stack *p);
int push(stack *p, Nodo n);
The short answer -- in this code:
int push(stack * p, Nodo n){
stack nuevo = (stack)malloc(sizeof(Nodo));
if(nuevo == NULL){
return 300;
}
*nuevo = n;
if(empty(*p)){
nuevo->next = NULL;
}
else{
nuevo->next = *p;
*p = nuevo;
}
return 301;
}
The *p = nuevo; should come after the else, not inside it. It applies regardless. The longer answer:
There are several problems with your stack code, including mismanagement of malloc'd memory. I suggest a simpler stack design, along the lines:
struct nodo {
char caracter;
struct nodo *next;
};
typedef struct nodo Nodo;
typedef Nodo *stack;
void inicializa(stack *p);
bool empty(stack p);
char top(stack p);
char pop(stack *p);
int push(stack *p, char c);
void inicializa(stack *p) {
*p = NULL;
}
bool empty(stack p) {
return (p == NULL);
}
int push(stack *p, char caracter) {
Nodo *nuevo = malloc(sizeof(*nuevo));
if (nuevo == NULL) {
return 300;
}
nuevo->caracter = caracter;
if (empty(*p)) {
nuevo->next = NULL;
} else {
nuevo->next = *p;
}
*p = nuevo;
return 301;
}
char pop(stack *p) {
Nodo *copy = *p;
*p = copy->next;
char caracter = copy->caracter;
free(copy);
return caracter;
}
char top(stack p) {
return p->caracter;
}
This requires a revision of revisar() along the lines:
void revisar(char *inf, stack p)
{
char caracter;
char pos[MAX];
int i = 0;
int j = 0;
inicializa(&p);
while (inf[i] != '\0')
{
if (inf[i] >= '0' && inf[i] <= '9')
{
pos[j++] = inf[i++];
}
else if(inf[i] == '(')
{
(void) push(&p, inf[i++]);
}
else if (inf[i] == ')')
{
while (top(p) != '(')
{
pos[j++] = pop(&p);
}
if (top(p) == '(')
{
(void) pop(&p);
}
i++;
}
else
{
if (inf[i] == '+' || inf[i] == '-' || inf[i] == '*' || inf[i] == '/')
{
if (empty(p) || top(p) == '(')
{
(void) push(&p, inf[i++]);
if (empty(p))
{
printf("NNNNNNOOOOOOOOOOOOOOOOOOOOOO"); // Here it prints that the stack is still empty....
}
}
else
{
if (menorpre(top(p), inf[i]))
{
(void) push(&p, inf[i++]);
}
else
{
pos[j++] = pop(&p);
if (!empty(p))
{
if (top(p) != '(')
{
pos[j++] = pop(&p);
}
}
else
{
(void) push(&p, inf[i++]);
}
}
}
}
}
}
while (!empty(p))
{
pos[j++] = pop(&p);
}
pos[j]='\0';
printf("\n \n");
printf("i=%d, j=%d", i, j);
printf("LA CADENA EN POSFIJO ES: ");
puts(pos);
}
In my testing, I was able to get revisar("1+2", p); to produce:
% ./a.out
ddd
i=3, j=3LA CADENA EN POSFIJO ES: 12+
%
Which I'm guessing is what you're after. If you have more questions about this, make sure to add the definition of menorpre() to your code above as it's the piece that's missing that can't be reconstructed.

Trying to delete all the elements from HashTable with the status marked as closed

#include<iostream>
using namespace std;
enum Stare {DESCHIS=10, LUCRU=20, DUPLICAT=30, REZOLVAT=40, INCHIS=50};
struct Task
{
char *idTask;
char *data;
char *numeInginer;
int nivelComplexitate;
Stare stare;
};
struct List
{
Task *task;
List*next;
};
struct HashTable
{
List** vector;
int size;
};
List* creareNodLista(Task *task)
{
List*nod = (List*)malloc(sizeof(List));
nod->task = task;
nod->next = NULL;
return nod;
}
void initHashTable(HashTable &hTable, int size)
{
hTable.vector = (List**)malloc(sizeof(List*)*size);
hTable.size = size;
memset(hTable.vector, 0, sizeof(List*)*size);
}
int fhash(char c, int l)
{
return c%l;
}
void inserareNodLista(List*&list, List*nod)
{
nod->next = list;
list = nod;
}
void inserareNodHashTable(HashTable hTable, List*nod)
{ //determinarea pozitiei pe care se face inserarea
int index = fhash(nod->task->numeInginer[0],hTable.size);
//obtinerea listei in care se face inserarea
List*list = hTable.vector[index];
//inserare element nou in lista
inserareNodLista(list, nod);
//actualizare element in hashTable
hTable.vector[index] = list;
}
List* getHashTable(HashTable ht, char cheie)
{
int f = fhash(cheie, ht.size);
return ht.vector[f];
}
void printHashTable(HashTable ht)
{
for (char c = 'A'; c < 'Z'; c++)
{
List*lista = getHashTable(ht, c);
int count = 0;
while (lista)
{
count++;
printf("%d", count);
printf("%s\n", lista->task->idTask);
printf("%s\n", lista->task->data);
printf("%s\n", lista->task->numeInginer);
printf("%d\n", lista->task->nivelComplexitate);
printf("%d\n", lista->task->stare);
lista = lista->next;
}
if (count>1)
printf("\nColiziune\n\n");
}
}
int stergeNodHashTable(HashTable hTable, char*numeInginer)
{
int pozitie = 0;
pozitie = fhash(numeInginer[0], hTable.size);
if (hTable.vector[pozitie] == NULL)
return -1;
else
{
if (strcmp(hTable.vector[pozitie]->task->numeInginer, numeInginer) == 0)
{
if (hTable.vector[pozitie]->next == NULL)
{
free(hTable.vector[pozitie]->task->idTask);
free(hTable.vector[pozitie]->task->data);
free(hTable.vector[pozitie]->task->numeInginer);
free(hTable.vector[pozitie]->task);
free(hTable.vector[pozitie]);
hTable.vector[pozitie] = NULL;
}
else
{
List*lista = hTable.vector[pozitie];
hTable.vector[pozitie] = lista->next;
free(lista->task->idTask);
free(lista->task->data);
free(lista->task->numeInginer);
free(lista->task);
free(lista);
lista->next = NULL;
lista = NULL;
}
}
else
{
List*tmp = hTable.vector[pozitie];
while (tmp->next != NULL && strcmp(tmp->next->task->numeInginer, numeInginer) != 0)
tmp = tmp->next;
List*list = tmp->next;
if (list->next == NULL)
{
free(list->task->idTask);
free(list->task->numeInginer);
free(list->task->data);
free(list->task);
free(list);
tmp->next = NULL;
list = NULL;
}
else
{
List*tmp = list;
list = list->next;
free(tmp->task->idTask);
free(tmp->task->data);
free(tmp->task->numeInginer);
free(tmp->task);
free(tmp);
tmp->next = NULL;
tmp = NULL;
}
}
}
return pozitie;
}
void main()
{
FILE *pFile = fopen("Text.txt", "r");
Task *task = NULL;
HashTable ht;
initHashTable(ht, 29);
if (pFile)
{
while (!feof(pFile))
{
task = (Task*)malloc(sizeof(Task));
char id[50];
fscanf(pFile, "%s", &id);
task->idTask = (char*)malloc(strlen(id) + 1);
strcpy(task->idTask, id);
char data[50];
fscanf(pFile, "%s", data);
task->data = (char*)malloc(strlen(data) + 1);
strcpy(task->data, data);
char numeInfiner[50];
fscanf(pFile, "%s", numeInfiner);
task->numeInginer = (char*)malloc(strlen(numeInfiner) + 1);
strcpy(task->numeInginer, numeInfiner);
fscanf(pFile, "%d", &task->nivelComplexitate);
fscanf(pFile, "%d", &task->stare);
//creare element lista
List*nod = creareNodLista(task);
//inserare element in hashTable
inserareNodHashTable(ht, nod);
}
fclose(pFile);
for (char c = 'A'; c < 'Z'; c++)
{
List *lista = getHashTable(ht, c);
while (lista)
{
if (lista->task->stare == 50)
stergeNodHashTable(ht, lista->task->numeInginer);
}
}
printHashTable(ht);
}
}
I am trying to delete from hashTable all the elements with status marked as closed. The delete function is working fine but when i call it for al the hashtable, it got me error: lista->task was 0xDDDDDD. I cant understand why. Please help me!

Pointer to FILE nulling itself without being used at all

in the following code when ran will produce a Segmentation Fault, due to a FILE* being passed to fclose which contains no address (NULL).
I'm wondering why this is happening, the FILE* isn't being used what so over.
The FILE* is named urandom and is passed to fclose in the main function.
Thanks
#include <stdio.h>
#include <stdlib.h>
struct property
{
char *name;
unsigned int value;
unsigned int owner;
unsigned int type;
};
struct player
{
unsigned int id;
unsigned int money;
unsigned int position;
};
int rollDice(FILE *);
int amountOfLines(FILE *);
int createArrayOfPtrs(int ,void ***);
int makeArryOfPropertyPtrs(int ,struct property **);
int FillArryPropertyData(struct property **,int ,FILE *);
int splitBuffer(char *,unsigned int *,char **);
int bufferPropertyFile(FILE *,char **,int );
i nt fillPropertyStruct(struct property *,unsigned int ,char *);
int main(void)
{
int linesInPropertyFile = 0;
struct property **arrayForProperties = 0;
//Open /dev/urandom for rollDice
FILE *urandom = fopen("/dev/urandom","rb");
FILE *propertyFile = fopen("/home/jordan/Documents/Programming/Monopoly Project/properties","rb");
if(propertyFile == NULL || urandom == NULL)
{
puts("ERROR: error in opening file(s)");
return 1;
}
linesInPropertyFile = amountOfLines(propertyFile);
//DEBUG
printf("%d is contained within \"linesInPropertyFile\"\n",linesInPropertyFile);
if(createArrayOfPtrs(linesInPropertyFile,(void ***)&arrayForProperties))
{
puts("ERROR: error from createArrayOfPointers()");
return 1;
}
//DEBUG
printf("Outside Pointer: %p\n",arrayForProperties);
if(makeArryOfPropertyPtrs(linesInPropertyFile,arrayForProperties))
{
puts("ERROR: error from createArrayOfPointersForProperties()");
return 1;
}
if(FillArryPropertyData(arrayForProperties,linesInPropertyFile,propertyFile))
{
puts("ERROR: error from FillArryPropertyData()");
}
//Close FILE stream for /dev/urandom
fclose(urandom);
fclose(propertyFile);
return 0;
}
int FillArryPropertyData(struct property **array,int amntOfProperties,FILE *fp)
{
int bufferUsed = 100;
int i = 0;
int returnValue = 0;
int returnValue2 = 0;
unsigned int money = 0;
char *name;
char *buffer;
rewind(fp);
while(returnValue == 0)
{
buffer = malloc(bufferUsed);
returnValue = bufferPropertyFile(fp,&buffer,bufferUsed);
if(returnValue && returnValue != -1)
{
puts("ERROR: error from bufferPropertyFile()");
return -1;
}
if(returnValue == -1)
{
break;
}
if(buffer[0] != '\0')
{
returnValue2 = splitBuffer(buffer,&money,&name);
}
if(returnValue2)
{
puts("ERROR: error in splitBuffer()");
return 1;
}
if(fillPropertyStruct(array[i],money,name))
{
puts("ERROR: error in fillPropertyStruct()");
return 1;
}
money = 0;
i++;
}
free(buffer);
return 0;
}
int fillPropertyStruct(struct property *array,unsigned int money,char *name)
{
int nameSize = 100;
int i = 0;
array->name = malloc(nameSize);
array->value = money;
while(1)
{
if(i >= nameSize)
{
void *tmp = realloc(array->name,nameSize * 2);
nameSize *= 2;
if(tmp)
{
array->name = tmp;
}
else
{
return -1;
}
}
if(name[i] == '\0')
{
break;
}
array->name[i] = name[i];
i++;
}
array->name[i] = '\0';
return 0;
}
int splitBuffer(char *buffer,unsigned int *money,char **name)
{
int i = 0;
int j = 1;
int nameSize = 100;
*name = malloc(nameSize);
while(1)
{
if(buffer[j] != '"')
{
(*name)[j-1] = buffer[j];
}
else
{
i++;
}
j++;
if(i)
{
break;
}
if(j >= nameSize)
{
void *tmp = 0;
tmp = realloc(*name,nameSize * 2);
nameSize = nameSize * 2;
if(tmp != NULL)
{
*name = tmp;
}
else
{
puts("ERROR: error in splitBuffer");
return -1;
}
}
}
name[j-1] = '\0';
while(buffer[j] != '$')
{
if(buffer[j] == '\0')
{
puts("ERROR: error in splitBuffer()");
return -2;
}
j++;
}
j++;
while(buffer[j] != '\0')
{
*money += (buffer[j] - '0');
if(buffer[j+1] != '\0')
{
*money *= 10;
}
j++;
}
printf("BUFFER: %s\n",buffer);
printf("NAME: %s\n",*name);
printf("MONEY: %d\n",*money);
return 0;
}
int bufferPropertyFile(FILE *fp,char **buffer,int i)
{
int j = (i - i);
if(feof(fp))
{
//-1 Returned if EOF detected
return -1;
}
char retr = 0;
while(1)
{
if(j + 1 >= i)
{
void *tmp = realloc(*buffer,i * 2);
if(tmp != NULL)
{
*buffer = tmp;
i = i * 2;
}
else
{
puts("ERROR: error in bufferPropertyFile()");
return -2;
}
}
retr = fgetc(fp);
if(retr == '\n' || feof(fp))
{
break;
}
(*buffer)[j] = retr;
j++;
}
(*buffer)[j] = '\0';
if(**buffer == '\0')
{
return -1;
}
return 0;
}
int rollDice(FILE *fp)
{
int seed = fgetc(fp);
srand(seed);
return (rand() % 6) + 1;
}
int amountOfLines(FILE *file)
{
int i = 0;
int retr = 0;
while(1)
{
retr = fgetc(file);
if(retr == EOF)
{
break;
}
if(retr == '\n' )
{
i++;
}
}
return i;
}
int createArrayOfPtrs(int numberOfPointers,void ***pointer)
{
void *tmp = malloc(numberOfPointers * sizeof (tmp));
if(tmp != NULL)
{
*pointer = tmp;
//DEBUG
printf("Pointer: %p\n",*pointer);
}
else
{
return 1;
}
return 0;
}
int makeArryOfPropertyPtrs(int numberOfPointers,struct property **pointer)
{
int i = 0;
void *tmp;
for(i = 0;i < numberOfPointers;i++)
{
tmp = malloc(sizeof(struct property));
if(tmp == NULL)
{
return 1;
}
pointer[i] = (struct property *)tmp;
}
return 0;
}
here it givest an access violation in splitBuffer on this line:
name[j-1]='\0';
which probably should be
(*name)[j-1]='\0';
indeed that memory is not allocated anywhere, in other words, undefined behaviour, which indeed in your case might overwrite the urandom variable: both urandom and name are allocated on stack so depending on value of j it might write over urandom..
apart from that, there might be more errors, the number and use of pointers/mallocs/reallocs and lack of frees is a bit scary
int createArrayOfPtrs(int ,void ***);
if(createArrayOfPtrs(linesInPropertyFile,(void ***)&arrayForProperties))
This is undefined behaviour, a (void***) is not compatible to a (struct property ***). Why do you even use it here, all the other functions use struct property pointers?
Since the array is located right before the file pointer in the local variables of main, maybe the problem is that the array creation/initialization overwrites urandom?

Resources