I'm trying to make a queue that dynamically increases by it's size by 3 when it reaches the size of 3 the first time. I haven't used malloc or realloc that much, but afaik they should be correct in the code
**Header:**
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
typedef char Titem;
/*The interface of queue */
#define MAXN 3
typedef enum {NOT_OK, OK } Tboolean;
typedef struct {
Titem array[MAXN];
int number_of_items;
} Tqueue;
void initialize_queue (Tqueue *Pqueue);
Tboolean enqueue( Tqueue *p, Titem item);
Tboolean dequeue( Tqueue *p, Titem *Pitem);
void print_queue(const Tqueue *Pqueue);
**Queue functions:**
#include "jono.h"
void initialize_queue ( Tqueue *Pqueue) {
int size = 0;
Pqueue->number_of_items = 0;
*Pqueue->array = (Titem) calloc (MAXN, sizeof(MAXN));
size = sizeof (Pqueue->array);
printf ("%d\n", size);
}
Tboolean enqueue( Tqueue *Pqueue, Titem item) {
int size = 0;
if (Pqueue->number_of_items >= MAXN) {
*Pqueue->array = (Titem) realloc (Pqueue->array, sizeof(Pqueue->array) + MAXN);
size = sizeof (Pqueue->array);
printf ("\%d", size);
Pqueue->array[Pqueue->number_of_items++] = item;
return(OK);
}
else {
Pqueue->array[Pqueue->number_of_items++] = item;
return (OK);
}
}
Tboolean dequeue( Tqueue *Pqueue, Titem *Pitem) {
int i;
if (Pqueue->number_of_items == 0)
return(NOT_OK);
else {
*Pitem = Pqueue->array[0];
for (i = 0 ; i < Pqueue->number_of_items-1 ; i++)
Pqueue->array[i] = Pqueue->array[i+1];
Pqueue->number_of_items--;
return (OK);
}
}
void print_queue (const Tqueue *Pqueue) {
int i;
printf("\nQueue now: \n\n");
for (i = 0 ; i < Pqueue->number_of_items ; i++ ) {
printf(" %c ", Pqueue->array[i]);
}
printf("\n\n");
}
**Main:**
#include "jono.h"
int main(void) {
Tqueue queue;
Tboolean succeed;
char chr;
initialize_queue(&queue);
printf("\nEnter a letter to be queued ");
printf("\nor digit 1 to dequeue a letter");
printf("\nor Return to quit a program\n");
chr = _getche();
while (chr != 10 && chr != 13) {
if (isalpha(chr)) {
succeed=enqueue(&queue, chr);
print_queue(&queue);
if (!succeed)
printf("\n Enqueue operation failed\n");
}
if (chr == '1') {
succeed = dequeue(&queue, &chr);
if (succeed) {
printf("\na letter dequeued %c ", chr);
print_queue(&queue);
}
else printf("\nDequeue operation failed\n ");
}
chr = _getche();
}
}
typedef struct {
Titem array[MAXN]; /* char array[3] */
int number_of_items;
} Tqueue;
*Pqueue->array = (Titem) calloc (MAXN, sizeof(MAXN));
You can not reserve space for an array (only pointers can use (m/c/re)alloc)
Related
I have a struct in this form:
typedef struct student{
double student_no;
char name[50];
char surname[50];
double phone_no;
char mail[50];
};
struct student person[100];
printf("Student's mail address: ");
scanf("%s", person[i].mail); //i use codeblocks and it works without the sign &
First I create an array of mails. Then I get a mail for user, then check if it is in my array that I created in the first place. I have to do it without strcmp(), and that's where I get stuck. Here is what I've tried so far:
char *e1, *e2;
int comp;
typedef struct info{
char email[50];
};
struct info mailaddress[0];
printf("Enter the mail address to search: ");
scanf("%s", mailaddress[0]);
for (int i = 0; i < u; i++) {
for (int j = i + 1; j < u; j++) {
e1 = person[i].mail;
e2 = mailaddress[j].email;
comp = 0;
while (*e1 && *e2) {
if (*e1 != *e2) {
comp = *e1 - *e2;
break;
}
++e1;
++e2;
}
if (comp == 0)
printf("%s\t %s %15.lf %15.lf %s\n",
person[i].name,
person[i].surname,
person[i].student_no,
person[i].phone_no,
person[i].mail);
}
}
Try like this
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
#define NO_MAX 20
#define NAME_MAX 20
#define SURNAME_MAX 20
#define PHONE_NO_MAX 20
#define MAIL_NO_MAX 50
struct student{
char student_no[NO_MAX + 1];
char name[NAME_MAX + 1];
char surname[SURNAME_MAX + 1];
char phone_no[PHONE_NO_MAX + 1];
char mail[MAIL_NO_MAX + 1];
struct student *ptr_next;
};
struct student *ptr_head = NULL;
struct student *ptr_position;
void enter_item(char *ptr_label, char *ptr_result, int max){
// enter item until pressed enter to finished
char tmp[256];
do {
printf("%s: ", ptr_label);
gets(tmp);
} while((strlen(tmp) > max));
strcpy(ptr_result, tmp);
}
void enter_list(void) {
char more;
struct student *ptr_new;
do{
// order dynamic memory
ptr_new = (struct student *) malloc(sizeof(struct student));
if(ptr_new) {
// enter item
enter_item("student_no", ptr_new->student_no, NO_MAX);
enter_item("name", ptr_new->name, NAME_MAX);
enter_item("surename", ptr_new->surname, SURNAME_MAX);
enter_item("phone_no", ptr_new->phone_no, PHONE_NO_MAX);
enter_item("mail", ptr_new->mail, MAIL_NO_MAX);
// next item
ptr_new-> ptr_next = ptr_head;
ptr_head = ptr_new;
// enter item again or not
printf("- again(Y/N)? -");
do{
more = toupper(getch());
} while(!(more=='Y' || more=='N'));
printf(" %c\n\n", more);
}
else {
printf("Memory isn't enough!\n");
break;
}
} while(more == 'Y');
}
void search_mail() {
// enter mail
struct student *ptr_search;
ptr_search = (struct student *) malloc(sizeof(struct student));
enter_item("mail searching", ptr_search->mail, MAIL_NO_MAX);
char *mail = ptr_search->mail;
// searching mail
ptr_position = ptr_head;
while(ptr_position) {
if(strcmp(mail, ptr_position->mail) != 0) {
ptr_position = ptr_position-> ptr_next;
}
else {
printf("Email is found\n");
return;
}
}
printf("Email isn't found!\n");
}
int main()
{
enter_list();
search_mail();
return 0;
}
Result:
bool streq(char *a, char *b)
{
while (*a && *b && *a != *b)
a++, b++;
return !*a && !*b;
}
So i have this program that has a structure and an array. The array is conj_jogos which is an array of a structure called jogo with MAX_SIZE (MAX_SIZE being 5).
Structure:
typedef struct
{
int id;
char equipas[2][1024];
int pont[2];
char nome[MAX_CHARS];
} jogo;
So to create this array i allocated memory in my main function like this:
int main()
{
char nome_jg[MAX_CHARS], team1[MAX_CHARS], team2[MAX_CHARS];
int score1;
int score2;
int i;
conj_jogos = (jogo*)calloc(MAX_SIZE,sizeof(jogo));
while ((c = getchar()) != x)
scanf("%1023[^:\n]:%1023[^:\n]:%1023[^:\n]:%d:%d",nome_jg,team1,team2,&score1,&score2);
remove_esp(nome_jg); /*removes the 1st char if its a space*/
a(nome_jg,team1,team2,score1,score2);
ident++;
}
free(conj_jogos);
return 0;
}
The problem is that valgrind is saying that i have a heap overflow on the "a" function and i dont know why so if someone can help i would appreciate it a lot.
Program:
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* Max chars for a word*/
#define MAX_SIZE 5 /*Max size for an array*/
jogo *conj_jogos; /*array that saves the jogos*/
static int size_until2 = 0; /*count the size of conj_jogos*/
void a(char nome_jg[],char team1[],char team2[],int score1,int score2)
{
if (jogo_in(nome_jg) == 1) //confirms if the string nome_jg is in conj_jogos
{
printf("%d Jogo existente.\n",line);
line++;
}
else if ((nome_in_sis(team1) == 0) || (nome_in_sis(team2) == 0)) //confirms if the strings team1 or team2 are in sistem_eq
{
printf("%d Equipa inexistente.\n",line);
line++;
}
else
{
if (size_until2 < MAX_SIZE)
{
conj_jogos[size_until2] = cria_jogo(nome_jg,team1,team2,score1,score2);
size_until2++;
line++;
}
else
{
jogo *temp;
size_until2++;
temp = realloc(conj_jogos,sizeof(jogo)*(size_until2+1));
free(conj_jogos);
conj_jogos = temp;
conj_jogos[size_until2] = cria_jogo(nome_jg,team1,team2,score1,score2);
size_until2++;
line++;
free(temp);
}
}
}
I cannot re-run the code because so much relevant functions are not included in your code. But I would try :
conj_jogos = realloc(conj_jogos,sizeof(jogo)*(size_until2+1));
instead of :
temp = realloc(conj_jogos,sizeof(jogo)*(size_until2+1));
And you may also try:
*(conj_jogos + (size_until2 * sizeof(jogo))) = cria_jogo(nome_jg,team1,team2,score1,score2);
size_until2++;
Instead of:
conj_jogos[size_until2] = cria_jogo(nome_jg,team1,team2,score1,score2);
size_until2++;
I don't know if my problem is a memory leak, or i'm not acessing the hashtable in the correct way.
My hash.h
#define HASHSIZE 31
#define EMPTY ""
#define DELETED "-"
typedef char KeyType[9];
typedef void *Info;
typedef struct entry
{
KeyType key;
Info info;
}Entry;
typedef Entry HashTable[HASHSIZE];
My hash.c
int Hash(KeyType k){
return atoi(k)%HASHSIZE;
}
void InitializeTable(HashTable t){
for(int i=0; i < HASHSIZE; i++){
strncpy(t[i].key,EMPTY,9);
}
}
void ClearTable(HashTable t){
InitializeTable(t);
}
void InsertTable_LP(HashTable t, KeyType k, Info i){
int a = 0;
int hash = Hash(k);
while((a<HASHSIZE)
&& strcmp(t[hash].key,EMPTY)!=0
&& strcmp(t[hash].key,DELETED)!=0 ){
hash = (hash + 1) % HASHSIZE;
a++;
}
strncpy(t[hash].key,k,9);
t[hash].info = i;
printf("Value of info is %d\n",(int)t[hash].info);
}
int RetrieveTable_LP(HashTable t, KeyType k){
int a=0;
int hash = Hash(k);
while(a<HASHSIZE
&& strcmp(t[hash].key,k)!=0
&& strcmp(t[hash].key,EMPTY)!=0){
hash=(hash+1) % HASHSIZE;
a++;
}
if(strcmp(t[hash].key,k)==0)
return hash;
return -1;
}
int main(){
HashTable *t = malloc(HASHSIZE*sizeof(Entry));
int valores[] = {1,2,3,4,5,6,7,8,9};
ClearTable(*t);
InsertTable_LP(*t,"1",valores);
InsertTable_LP(*t,"2",valores+1);
InsertTable_LP(*t,"3",valores+2);
InsertTable_LP(*t,"4",valores+3);
InsertTable_LP(*t,"5",valores+4);
int pos = RetrieveTable_LP(*t,"2");
if(pos==-1){
printf("Error\n");
}
else
printf("Position %d\n",pos);
printf("okay %d\n",(int)t[pos]->info);
printf("asdasdas\n");
return 1;
}
My output is
Value of info is 1537727040
Value of info is 1537727044
Value of info is 1537727048
Value of info is 1537727052
Value of info is 1537727056
Position 2
okay 0
If anyone could explain me, thanks in advance.
valores is an array. You are inserting Info which has been typedefed to void *. You need to fix those things.
Your malloc is not necessary the reason why that wasn't obvious is because it was hidden by the way you typedefd the HashTable, don't ever do that, the following code works as you expected yours to do
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASHSIZE 31
#define EMPTY ""
#define DELETED "-"
typedef char KeyType[9];
typedef void *Info;
typedef struct entry
{
KeyType key;
Info info;
}Entry;
typedef Entry HashTable[HASHSIZE];
int Hash(KeyType k){
return atoi(k)%HASHSIZE;
}
void InitializeTable(HashTable t) {
int i;
for(i=0; i < HASHSIZE; i++) {
strncpy(t[i].key, EMPTY, 9);
}
}
void ClearTable(HashTable t) {
InitializeTable(t);
}
void InsertTable_LP(HashTable t, KeyType k, Info i){
int a = 0;
int hash = Hash(k);
while((a<HASHSIZE) && strcmp(t[hash].key, EMPTY) !=0 && strcmp(t[hash].key, DELETED) !=0 ) {
hash = (hash + 1) % HASHSIZE;
a++;
}
strncpy(t[hash].key, k, 9);
t[hash].info = i;
printf("Value of info is %p\n", t[hash].info);
}
int RetrieveTable_LP(HashTable t, KeyType k){
int a=0;
int hash = Hash(k);
while(a<HASHSIZE
&& strcmp(t[hash].key,k)!=0
&& strcmp(t[hash].key,EMPTY)!=0){
hash=(hash+1) % HASHSIZE;
a++;
}
printf("%s, %s\n", t[hash].key, k);
if(strcmp(t[hash].key, k)==0)
return hash;
return -1;
}
int main(){
/*
* You don't need to malloc, since HashTable is an array,
* and it does not need to be a pointer, since it decays
* to one when passed as such.
*/
HashTable t;// = malloc(HASHSIZE * sizeof(Entry));
int valores[] = {1,2,3,4,5,6,7,8,9};
ClearTable(t);
InsertTable_LP(t,"1",valores);
InsertTable_LP(t,"2",valores+1);
InsertTable_LP(t,"3",valores+2);
InsertTable_LP(t,"4",valores+3);
InsertTable_LP(t,"5",valores+4);
int pos = RetrieveTable_LP(t, "2");
if(pos==-1) {
printf("Error\n");
}
else
{
printf("Position %d\n",pos);
printf("okay %p\n", t[pos].info);
}
printf("asdasdas\n");
return 1;
}
your typedef of the HashTable makes it hard to know what to do with a HashTable type variable, that is not a very good use of typedef.
Also the second printf will be executed regardless of the condition
else
printf("Position %d\n",pos);
printf("okay %d\n",(int)t[pos]->info);
you need to add {
else
{
printf("Position %d\n",pos);
printf("okay %d\n",(int)t[pos]->info);
}
Alright sorry for creating another question but the last one got overwhelmed and chaotic.
So I'm making a hash table which inserts words from a file (tokens) and after I have inserted them I need to sort them. The program template was given, the only functions that weren't complete were : insert_ht() , clear_ht() and compare. Even though I've done tons of search about qsort with compare, the program doesn't sort the frequencies (number of times each word was inserted) . I want em sorted from the highest to lowest.
Here is the code : "note that i shouldn't change any function except insert_ht() , clear_ht() and compare
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("prin tin for \n");
for (i=1; i < argc; i++)
{
printf("prin tin fopen \n");
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
printf("prin tin process \n");
Process(fp);
fclose(fp);
}
print_ht();
//clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators)){
printf("prin tin insert %s \n",s);
insert_ht(s);
}
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
printf("bike stin hash \n");
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
printf("VGAINEIIIIIIIIIIIIII %d \n",hv);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
printf("bike stin insert %s \n",token);
unsigned int hashval = hash(token);
struct node *new_list;
if (htable[hashval]==NULL){
printf("mesa stin prwti if %u %s \n",hashval,token);
//token = strdup(token);
new_list = malloc(sizeof(link));
new_list->token = strdup(token) ;
new_list->freq = 1;
new_list->next = htable[hashval];
htable[hashval] = new_list;
size++;
}else {
htable[hashval]->freq++;
}
printf("ta evale epitixws \n");
}
void clear_ht()
{
int i;
for(i=0; i<HTABLE_SIZ; i++) {
while(htable[i]->token!=NULL) {
htable[i]->token=NULL;
htable[i]->freq=NULL;
free(htable[i]);
}
}
}
int compare(const void *elem1, const void *elem2)
{
const struct node *p1 = elem1;
const struct node *p2 = elem2;
if (p1->freq > p2->freq)
return(+1);
else if (p1->freq < p2->freq)
return(-1);
else
return(0);
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
Ι found the solution. Apparently for some reason my compare function was wrong.
I still haven't figured out why but here is the correct one, hopefully someone else will find this post helpful!
int compare(const void *elem1, const void *elem2)
{
return (*(link*)elem2)->freq - (*(link*)elem1)->freq;
}
I'm trying to store strings into dynamical allocated memory. I'm able to break the strings down and store them within the members of the struct and print them perfectly within the function readFile, but when it comes to printing it in main, it's only printing the last scan and everything else is null. I'm thinking that maybe I'm not allocating the array of structures correctly. Here's my program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef _MSC_VER
#include <crtdbg.h> // needed to check for memory leaks (Windows only!)
#endif
#define MEM_ERROR printf("Not enough memory\n")
#define FLUSH while( getchar() != '\n' )
typedef struct
{
char id[5];
char *name;
int *sales;
int total;
int low;
int high;
}PERSON;
typedef struct
{
int worker;
int weeks;
PERSON *pAry;
}HEADER;
// Function Declaration
void valiFile(char nameIn[]);
FILE* openFile(char nameIn[]);
void getHeader(FILE* fpFile, HEADER *pHead);
PERSON* aloPerson(int workers);
void readFile(FILE* fpFile, HEADER *pHead);
char* aloName(HEADER *pHead, int strCount);
void repeat(char nameIn[]);
int main ( void )
{
// Local Declaration
FILE* fpFile;
char nameIn[25];
char *endPro = "end";
HEADER *pHead = (HEADER*)calloc(1, sizeof(HEADER));
// Statement
printf("Please select file to to open.\nsales or sales_2: ");
scanf("%s", nameIn);
FLUSH;
do
{
valiFile(nameIn);
fpFile = openFile(nameIn);
getHeader(fpFile, pHead);
readFile(fpFile, pHead);
//printf("%s\n", pHead->pAry[0].id);
//free(pHead);
repeat(nameIn);
}
return 0;
}// main
/* ========== valiFile ==========
========== */
void valiFile(char nameIn[])
{
// Local Declaration
char *file = "sales";
char *file2 = "sales_2";
int i;
int check = 0;
// Statement
do
{
for(i = 0; nameIn[i]; i++)
{
nameIn[i] = tolower(nameIn[i]);
}
if(strcmp(file, nameIn) != 0)
{
if(strcmp(file2, nameIn) != 0)
{
printf("\nPlease enter a valid file.\n");
printf("sales or sales_2: ");
scanf("%s", nameIn);
FLUSH;
}
else
check = 1;
}
else
check = 1;
}
while(check != 1)
;
return;
}// valiFile
/* ========== openFile ==========
========== */
FILE* openFile(char nameIn[])
{
// Local Declaration
FILE* fpFile;
char *strSale = "sales";
// Statement
if(strcmp(strSale, nameIn) == 0)
{
fpFile = fopen("sales.txt", "r");
if(fpFile == NULL)
{
printf("File didn't read correcty.\n");
exit(100);
}
}
else
{
fpFile = fopen("sales_2.txt", "r");
if(fpFile == NULL)
{
printf("File didn't read correcty.\n");
exit(100);
}
}
return fpFile;
}// openFile
/* ========================= getHeader ========================
============================================================*/
void getHeader(FILE* fpFile, HEADER *pHead)
{
// Local Declaration
int worker, salesWeek, i;
PERSON *list;
// Statement
fscanf(fpFile, "%d %d", &worker, &salesWeek);
list = aloPerson(worker);
HEADER header = {worker, salesWeek, list};
*pHead = header;
return;
}// getHeader
/* aloPerson
*/
PERSON* aloPerson(int worker)
{
// Local Declaration
PERSON *list;
// Statement
list =(PERSON*)calloc(worker, sizeof(PERSON));
if(list == NULL)
{
MEM_ERROR, exit(103);
}
return list;
}// aloPerson
/* readFile
*/
void readFile(FILE* fpFile, HEADER *pHead)
{
// Local Declaration
char temp[50];
int strCount = 0;
char *loc;
char *ptr;
int i;
// Statement
fscanf(fpFile, "%*d %*d");
for(i = 0; i < pHead->worker; i++)
{
while(fgets(temp, sizeof(temp), fpFile))
{
ptr = temp;
loc = strchr(temp, ' ');
strncpy(pHead->pAry[i].id, temp, (loc - ptr));
ptr += (loc - temp);
*ptr++;
loc = strchr(temp, ';');
strCount = (loc - ptr);
pHead->pAry[i].name = aloName(pHead, strCount);
strncpy(pHead->pAry[i].name, ptr, (loc - ptr));
ptr += (loc - ptr);
printf("%s\n", pHead->pAry[i].name);
}
}
return;
}// readFile
/* aloName
*/
char* aloName(HEADER *pHead, int strCount)
{
// Local Declaration
char *names;
// Statement;
names = malloc((strCount + 1)*sizeof(char));
return names;
}