Why there is an infinite for loop? - c

The programm falls in the infinite loop. But arr->count printf prints a normal value (4, for example). count has a type unsigned int and arr is a pointer to int. What's the problem here? loop prints arr values at first and then continues to print trash values
In arrat_get it prints array just fine
struct _arr {
size_t count;
int* arr;
} ;
typedef struct _arr array_t;
array_t* array_get(FILE* file){
int* arr = NULL;
size_t count = 0;
array_t* arr_t;
array_t temp;
int i = 0;
if (!file) {
fprintf(stderr, "there is no such file\n");
return;
}
if (fscanf(file, "%u", &count) == EOF) {
fprintf(stderr, "can't read count from file\n");
return;
}
temp = array_create(arr, count);
arr_t = &temp;
printf("%i\n", arr_t->count);
for (i = 0; i < arr_t->count; i++){
if (fscanf(file, "%d", &arr_t->arr[i]) == EOF) {
fprintf(stderr, "can't read arr from file\n");
return;
}
}
for (i = 0; i<arr_t->count; i++)
printf("%d ", arr_t->arr[i]);
printf("\n");
return arr_t;
}
int main(){
array_t* arr_t;
int i = 0;
printf("enter count and arr:\n");
arr_t = array_get(stdin);
printf("count in main=%u\n", arr_t->count);
for (i = 0; i<arr_t->count; i++)
printf("%d ", arr_t->arr[i]);
getch();
return 0;
}

This is not the solution of your problem, but may help you to find it:
#include <stdio.h>
#include <stdlib.h>
struct _arr {
int count;
int* arr;
} ;
int main(){
int i = 0;
struct _arr myArray[10];
for (i = 0; i < 10; i++) {
myArray[i].count = 9;
myArray[i].arr = &myArray[i].count;
}
for (i = 0; i < (myArray->count); i++)
printf("%d %p\n", myArray[i].count, myArray[i].arr);
return 0;
}
OUTPUT:
Compiling the source code....
$gcc main.c -o demo -lm -pthread -lgmp -lreadline 2>&1
Executing the program....
$demo
10 0x7fffeb764c00
10 0x7fffeb764c10
10 0x7fffeb764c20
10 0x7fffeb764c30
10 0x7fffeb764c40
10 0x7fffeb764c50
10 0x7fffeb764c60
10 0x7fffeb764c70
10 0x7fffeb764c80

Related

Selection sort not working as expected (C language)

I have to sort an array of structs with selection sort, after I read them from a file.txt.
My algorithm is not working as expected, but it always avoid to sort them and it print the struct in decreasing order.
Example of file.txt :
P0 "ANTONIO" 2000 4
P1 "BARTOLOMEO" 1995 6
P2 "CARLO" 2020 1
P3 "DEMETRIO" 1960 2
P4 "ETTORE" 1920 3
P5 "FRANCESCO" 1950 5
Input: 2 5 3 1 6 4
Output: 4 6 1 3 5 2
What am I doing wrong?
Code below:
#include <stdio.h>
#include <stdlib.h>
#define N 7
struct persona
{
char codice[10];
char nome[30];
int anno[10];
int reddito[10];
};
int main()
{
FILE* fp;
fp = fopen("Testo.txt", "r");
struct persona* persona = malloc(sizeof(struct persona) * N);
int i = 0;
int j = 0;
if (fp != NULL)
{
while (i < N-1)
{
fscanf(fp, "%s %s %s %s",
persona[i].codice,
persona[i].nome,
persona[i].anno,
persona[i].reddito);
i++;
}
}
else
{
perror("Errore");
}
fclose(fp);
for(i=0; i<N-2; i++)
{
int min = persona[i].reddito;
for(j=i+1; j<N-1; j++)
{
if(persona[j].reddito < persona[i].reddito)
{
min = persona[j].reddito;
}
persona[N] = persona[j];
persona[j] = persona[i];
persona[i] = persona[N];
}
}
for(i=0; i<N-1;i++)
{
printf("%s\t %s\t %s\t %s\n",
persona[i].codice,
persona[i].nome,
persona[i].anno,
persona[i].reddito);
}
}
You have 6 lines in the file, but you have defined N as 7. It should be updated to 6.
while (i < N-1)
You are reading the first N-2, that is, 5 lines from the file. The 6th line is not being read. Same goes for other loops in the code using N.
int anno[10];
int reddito[10];
You do not need integer array to read the numeric fields in file, an integer should suffice.
As mentioned by #WhozCraig in the comments, the selection sort algorithm is incorrect. Here's the updated code for reference:
#include <stdio.h>
#include <stdlib.h>
#define N 6
typedef struct persona
{
char codice[10];
char nome[30];
int anno;
int reddito;
} PERSONA;
int main()
{
FILE *fp;
if ((fp = fopen("file.txt", "r")) == NULL)
{
perror("\nFile not found");
exit(1);
}
PERSONA *persona = malloc(sizeof(struct persona) * N);
int i = 0, j;
while (i < N)
{ if (fscanf(fp, "%s %s %d %d", persona[i].codice, persona[i].nome, &persona[i].anno, &persona[i].reddito) == EOF) {
break;
}
i++;
}
fclose(fp);
PERSONA temp;
/* selection sort */
for (i = 0; i < N - 1; i++)
{
int jMin = persona[i].reddito;
for (j = i + 1; j < N; j++)
{
if (persona[j].reddito < persona[jMin].reddito)
{
jMin = j;
}
}
if (jMin != i)
{
temp = persona[i];
persona[i] = persona[jMin];
persona[jMin] = temp;
}
}
for (i = 0; i < N; i++)
{
printf("\n%s\t %s\t %d\t %d", persona[i].codice, persona[i].nome, persona[i].anno, persona[i].reddito);
}
}
Further improvements:
You could also calculate the number of lines in the file in the code instead of relying on a hardcoded value N.
The statement to check sets only the min only if this statement is true
if(persona[j].reddito < persona[i].reddito)
try using the qsort function
int cmpfunc (const void * a, const void * b) {
struct persona *p1 = (struct persona *)a;
struct persona *p2 = (struct persona *)b;
if(p1->reddito < p2->reddito) return -1;
if(p1->reddito > p2->reddito) return 1;
return 0;
}
and instead of the for loop, use
qsort(persona, N, sizeof(struct persona), cmpfunc);

How to check the frequency of words in a two-dimensional arry using pointers

Hello i am trying to find the frequncey of words in tow dimensional arry but im having problem with my codes so far this is what i have done i tried to find whats wrong using debugger but i cant find anything usefull im new to coding so i would be really happy if someone can tell me the problem
I pointed out where im having problem in my code
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void freeFunction(char** arry, int size);
void insertArry(char** words, int countWords);
void wordFrequency(char** words, int countWords);
int main()
{
char** words=NULL;
int count = NULL;
insertArry(words, &count);
wordFrequency(words,count);
}
void insertArry(char** words, int* countWords)
{
char buffer[11];
int numberC;
printf("How many words?: ");
scanf("%d", &numberC);
getchar();
words = (char**)malloc(numberC * sizeof(char*));
if (words == NULL)
{
printf("No memory");
exit(1);
}
for (int i = 0; i < numberC; i++)
{
printf("Enter word: ");
gets_s(buffer, 11);
words[i] = (char*)malloc(strlen(buffer) + 1);
if (words == NULL)
{
freeFunction(words, i);
exit(1);
}
strcpy(words[i], buffer);
}
*countWords = numberC;
}
void freeFunction(char** arry, int size){
printf("No memory");
for (int j = 0; j < size; j++)
{
free(arry[j]);
}
free(arry);
}
void wordFrequency(char** words, int countWords)
{
int counter = 0;
for (int i = 0; i < countWords; i++) {
for (int j = i + 1; j < countWords; j++)
{
if(strcmp(words[i],words[j])==0) /// ***THIS IS WHERE MY PROBLEM RELAY ITS GIVING ME WEIRD ADDRESSES***
counter += 1;
}
printf("%s:%d",words[i], counter);
counter = 0;
}
}

Parenthesis balance program crashing(c)

Good afternoon, i am trying to do a program that checks whether if a expression has its parentheses balanced or not but because of some problem that i can't quite find out the program is crashing, could somebody help me find a way so that the program works?
In
a * b - (2 + c)
Out
Correct
or
In
)3+b * (2-c)(
Out
Incorrect
The program should check only for parantheses and i am supposed to implement linear lists on the code.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SUCESSO 1 //Succes
#define FALHA -1 //Failure
#define CELULA_INVALIDA 0 //Invalid key
#define TAMANHO_MAXIMO 1000 //Max size
typedef struct{
char exp[1000];
unsigned int chave; //key
}celula; //node
typedef struct{
celula celulas[TAMANHO_MAXIMO]; //vector of nodes
unsigned int tamanho; //size of the list
}fila; //list
int criarFilaVazia(fila * ent){ //create an empty list
ent->tamanho = 0;
return(SUCESSO);
}
int insFinal(fila * ent, celula node){ //put a node on the end of the list
unsigned int i;
celula aux;
if(ent->tamanho == TAMANHO_MAXIMO){
return(FALHA);
}
else{
ent->celulas[ent->tamanho] = node;
ent->tamanho++;
return(SUCESSO);
}
}
void mostrarCelula(celula ent){ //show node
printf("%s \n", ent.exp);
}
void mostrarFila(fila ent){ //show entire list
unsigned int i;
if(ent.tamanho == 0){
printf("Fila vazia");
}
else{
printf("A fila possui %u element \n", ent.tamanho);
for(i=0; (i < ent.tamanho); i++){
printf("Elemento %u \n \n", (i+1));
mostrarCelula(ent.celulas[i]);
}
}
}
int main(){
int i, j;
fila exp;
celula aux;
scanf("%s", &aux.exp);
getchar();
aux.chave = 0;
insFinal(&exp, aux);
for(i = 0; i < strlen(exp.celulas[0].exp); i++){//checks all the array
if(exp.celulas[0].exp[i] == '('){//if there is an opening
for(j = i; j < strlen(exp.celulas[0].exp); j++){
if(exp.celulas[0].exp[j] == ')'){//should be and ending
exp.celulas[0].exp[i] = 0;//removes if balanced
exp.celulas[0].exp[j] = 0;
}
}
}
}
//checks for remaining parentheses and prints the output
for(i = 0; i < strlen(exp.celulas[0].exp); i++){
if(exp.celulas[0].exp[i] == '(' || exp.celulas[0].exp[i] == ')'){
printf("Incorreta"); //incorrect
}
else{
printf("Correta"); //correct
}
}
return 0;
}
[enter image description here][1]
Error message: https://i.stack.imgur.com/aeSn5.png
it says ex06 stopped working
Your program is crashing inside insFinal because the ent parameter passed in from main has uninitialized data. Hence, undefined behavior. Ammend these two lines at the beginning of main:
fila exp;
celula aux;
With this:
fila exp = {0};
celula aux = {0};
That will zero-init both.
The thing I don't get is what all these data structures are used for. Nor do I understand the double-nested for loop for checking the balance. Checking for a balanced set of parentheses in an expression should be as simple as this:
int areParenthesesBalanced(const char* str)
{
int balance = 0;
int len = str ? strlen(str) : 0;
for (int i = 0; i < len; i++)
{
if (str[i] == '(')
{
balance++;
}
else if (str[i] == ')')
{
balance--;
if (balance < 0)
{
return 0;
}
}
}
return (balance == 0) ? 1 : 0;
}
int main() {
char str[1000];
scanf("%s", str);
if (areParenthesesBalanced(str))
{
printf("Incorreta\n");
}
else
{
printf("Correta\n");
}
return 0;
}

C - char** not printing correctly after being returned from function

I am trying to return a char** from a function to main so I can do stuff with it, but when I print it out it gives me random characters. I'm at a loss.
main VV
// ./main < data/filelist.txt
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hist.h"
int main(){
int count = 0;
int i;
char** files = read(&count);
displayList(files, count);
char** array = splitFiles(files, count);
printf("IN MAIN: array[0] - %s\n", array[0]);
Histogram* p;
printf("here\n");
int histArrayCount = calcHistogram(&array[0], &count, &p);
printf("here\n");
displayHistogram(p, histArrayCount);
printf("here\n");
}
hist.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hist.h"
int calcHistogram (char** a, int* count, Histogram** q) {
int i, k;
int j = 0;
int histArrayCount = 0;
Histogram* p = (Histogram*)malloc((*count) * sizeof(Histogram));
for (k = 0; k < *count; k++) {
p[k].num = "1";
p[k].freq = 0;
}
for (i = 0; i <= *count; i++) {
while ((strcmp(p[j].num, "1") != 0) && (strcmp(p[j].num, a[i]) != 0)) {
j++;
}
if (strcmp(p[j].num, "1") == 0) {
p[j].num = a[i];
p[j].freq = 1;
histArrayCount++;
}
else if ((strcmp(p[j].num, a[i]) == 0)) {
p[j].freq += 1;
}
else {
printf("ERROR\n");
}
j = 0;
}
*q = p;
return histArrayCount;
}
void displayHistogram (Histogram* p, int histArrayCount) {
int i;
for (i = 0; i < histArrayCount - 1; i++) {
printf("value %s: freq %d\n", p[i].num, p[i].freq);
}
printf("\n");
}
char** splitFiles(char** files, int count) {
int i;
char** array = (char**)malloc((count)*sizeof(char*));
FILE* fp;
int c = 0;
for(i = 0; i < count; i++) {
char buff[255];
fp = fopen(files[i], "r");
array[i] = fgets(buff, 255, (FILE*)fp);
printf("%d : %s\n", i, buff);
}
printf("array[0] = %s\n", array[0]);
return array;
}
void displayList(char** a, int c) {
int i;
for (i = 0; i < c; i++) {
printf("File %d: %s\n", i, a[i]);
}
printf("\n");
}
char** read(int* c){
int count = 0;
int i;
char** a = (char**)malloc(100*sizeof(char*));
for (i = 0; i< 100; i++) {
a[count] = (char*)malloc(100*sizeof(char));
count++;
}
count = 0;
int endOfFile = scanf("%s", a[count]);
while (endOfFile != EOF) {
count++;
endOfFile = scanf("%s", a[count]);
}
*c = count;
return a;
}
When I print the array at index 0 in here it gives me what is actually there, but when I do the same thing in main it does not. It gives me three random characters.
hist.h
typedef struct Histogram {
char* num;
int freq;
} Histogram;
char** read(int* c);
void displayList(char** a, int c);
int calcHistogram (char** a, int* c, Histogram** p);
void displayHistogram (Histogram* a, int histArrayCount);
char** splitFiles (char** files, int count);

Invalid pointer with pthread_join

#include <pthread.h> /* Thread related functions*/
#include <stdio.h> /* Standard buffered input/output */
#include <stdlib.h> /* Standard library functions */
#include <string.h> /* String operations */
struct element{
FILE* file1;
FILE* file2;
int alone;
};
int comp( const void* a, const void* b) //function for qsort
{
const int *a1 = (const int *)a; // casting pointer types
const int *b1 = (const int *)b;
return *a1 - *b1;
}
void* merge(void* filenames) //writes out files to two arrays, merges them and writes output to temp file and passes this tempfile through pthread_exit.
{
struct element* Data;
Data = (struct element*) filenames;
//char* fileA = Data->file1;
//char* fileB = Data->file2;
FILE* A = Data->file1;
FILE* B = Data->file2;
if(Data->alone!=1)
{
//A = fopen(fileA, "r");
int linesA = 0;
int val=0;
printf("FILE* A: %p \n", A);
rewind(A);
while(fscanf(A, "%d", &val) != EOF)
linesA++;
printf("scanf\n");
rewind(A);
int* intarrA = (int*) malloc(linesA*sizeof(int));
int i =0;
for(;fscanf(A, "%d", &val) != EOF; i++)
intarrA[i] = val;
fclose(A);
//FILE* B;
//B = fopen(fileB, "r");
int linesB = 0;
while(fscanf(B, "%d", &val) != EOF)
linesB++;
rewind(B);
int* intarrB = (int*) malloc(linesB*sizeof(int));
i =0;
for(;fscanf(B, "%d", &val) != EOF; i++)
intarrB[i] = val;
fclose(B);
int templength = linesA+linesB;
int* inttemp = (int*) malloc(templength*sizeof(int));
int help1 = 0;
int help2 = 0;
int temph = 0;
for(i=0; i<templength; i++)
{
if(help1 == linesA)
{
int j = 0;
for(j=help2; j<linesB; j++)
{
inttemp[temph] = intarrB[j];
temph++;
}
break;
}
else if(help2 == linesB)
{
int j = 0;
for(j=help1; j<linesA; j++)
{
inttemp[temph] = intarrA[j];
temph++;
}
break;
}
else if(intarrA[help1]==intarrB[help2])
{
inttemp[temph]=intarrA[help1];
help1++;
help2++;
temph++;
}
else if (intarrA[help1]<intarrB[help2])
{
inttemp[temph]=intarrA[help1];
help1++;
temph++;
}
else if(intarrA[help1]>intarrB[help2])
{
inttemp[temph]=intarrB[help2];
help2++;
temph++;
}
}
FILE* filetowrite;
filetowrite = tmpfile();
for(i=0; i<temph; i++)
fprintf(filetowrite ,"%d\n",inttemp[i]);
printf("Merged %d lines and %d lines into %d lines\n",linesA,linesB,temph);
// free(intarrA);
// free(intarrB);
// free(inttemp);
printf("thread exit\n");
pthread_exit((void*)filetowrite);
}
else{
pthread_exit((void*)Data->file1);
printf("ELSE MERGE \n");
}
}
void* worker(void* filen)
{
//left out to keep code short
}
int main(int argc, char **argv) //gets files through terminal, and sorts each one trhough worker function and then merges them with merge function and pthreads.
{
int zit =0;
void* tempf;
// tempf = malloc(sizeof(FILE));
argc = argc-1;
struct element* filenamelist; //I make an array of this to merge threads till there is only one element left
pthread_t *threadid;
threadid = (pthread_t*) malloc(sizeof(pthread_t)*argc);
int i;
for(i=1; i<=argc; i++) // part 1 passing the files to be qsorted
{
pthread_create(&threadid[i-1], NULL, worker, (void*) argv[i]);
}
//sorts each file fine. saves it as filename.sorted
for(i=0; i<argc; i++)
{
pthread_join(threadid[i], NULL);
}
printf(" DONE WORKER\n");
int mall=0;
int size = 0;
if(size%2 ==0)
size = argc/2;
else
size = argc/2 +1;
//int Osize = size;
int z=0;
int truth = 0;
// filenamelist = (struct element**) malloc(sizeof(struct element*)*argc);
// for(i=0; i<argc; i++)
filenamelist = (struct element*) malloc(argc*(sizeof(struct element)));
FILE** inputFiles = malloc(sizeof(FILE*) * (argc+argc));
for(i=1; i<=argc; i++) //creates a list of elements with file ptrs
{
filenamelist[(i-1)/2].alone = 0;
if(i==argc && i%2!=0)
{
char* tedious1 = (char*) malloc( (strlen(argv[i]) + 8 ));
//char* tedious1 = (char*) malloc((strlen(argv[i+1]+7))*sizeof(char));
strcpy(tedious1,argv[i]);
filenamelist[(i-1)/2].file1 = fopen(strcat(tedious1,".sorted"),"r");
filenamelist[(i-1)/2].file2 = NULL;
filenamelist[(i-1)/2].alone = 1;
free(tedious1);
}
else
{
char* tedious3 = (char*)malloc( (strlen(argv[i]) + 8 ));
strcpy(tedious3,argv[i]);
// printf("%s\n", tedious3);
if(i%2 ==0)
filenamelist[i/2].file2 = fopen(strcat(tedious3,".sorted"),"r");
else
filenamelist[i/2].file1 = fopen(strcat(tedious3,".sorted"), "r");
free(tedious3);
}
}
/* for(i=0; i<size; i++)
{
printf("THIS IS: %d\n", i);
if(filenamelist[i].alone ==1)
{
printf(" Alone \n");
printf(" %p \n", filenamelist[i].file1);
}
else
{
printf("1 %p \n", filenamelist[i].file1);
printf("2 %p \n", filenamelist[i].file2);
}
}*/
// pthread_t* threadid2;
// threadid2 = (pthread_t*) malloc(sizeof(pthread_t)*(2*argc));
int xyz = 0;
int arab = 0;
int saudi = 0;
while(size>1) //Iterates through list till only one element left
{
i = 0;
pthread_t* threadid2;
threadid2 = (pthread_t*) malloc(sizeof(pthread_t)*argc);
printf("before create: %d, %p \n", i, tempf);
for ( ; i<size;i++ )
{
pthread_create(&threadid2[i], NULL, merge, &filenamelist[i]); //<--- invalid pointer
printf("AFTER create: %d, %p \n", i, threadid2[i]);
}
i = 0;
for ( ; i<size; i++)
{
printf("before join JOIN: %d, %p \n", i, tempf);
pthread_join(threadid2[i], &tempf);
printf("AFTER JOIN: %d, %p \n", i, tempf);
if (i%2 == 0)
{
filenamelist[i/2].file1 = (FILE*)(tempf);
}
else
{
filenamelist[i/2].file2 = (FILE*)(tempf);
}
if(i%2==0 && i ==size-1)
filenamelist[i].alone = 1;
zit=0;
truth = 0;
while(zit<z)
{
if(inputFiles[zit] == (FILE*)(tempf))
truth = 1;
zit++;
}
if(truth != 1)
{
inputFiles[z] = (FILE*)(tempf);
z++;
}
}
if(size==1)
size = 0;
else if (size % 2 == 0)
size = size/2;
else
size = (size/2)+1;
free(threadid2);
}
pthread_t throwthread;
pthread_create(&throwthread, NULL, merge, &filenamelist[0]);
FILE* final;
pthread_join(throwthread, tempf);
int chd = 0;
final = (FILE*) tempf;
// if(0!=feof(tempf))
// rewind(tempf);
//rewind(filenamelist[0]->file1);
int finish = 0;
//printf("file 1:%p",tempf);
while(fscanf(final, "%d", &chd) != EOF)
finish++;
rewind(final);
int* finarr = (int*) malloc(finish*sizeof(int));
int xx =0;
for(;fscanf(final, "%d", &chd) != EOF; xx++)
finarr[xx] = chd;
//fclose(filetosort);
//qsort(intarr, i, sizeof(int),comp);
FILE* filetowrites;
filetowrites = fopen("sorted.txt", "w");
for(xx=0; xx<finish; xx++)
fprintf(filetowrites, "%d\n", finarr[xx]);
fclose(filetowrites);
for(xx=0; xx<z; xx++)
fclose(inputFiles[xx]);
free(inputFiles);
free(filenamelist);
free(finarr);
return 0;
}//end main func
This gives me an invalid pointer error. threadid is a pthread_t* pointing to an array.
I'm passing in a file pointer typecasted into a void* for the pthread_exit((void*)fileptr);
where fileptr is some FILE*.
And would it be okay to access tempf as (FILE*) tempf?
EDIT:I've tried everything that makes sense to me. Don't know why threadid2[i] or tempf would be an invalid pointer in the merge function. This is not something i can debug, Help please!
ERROR OCCURS ON FIRST JOIN

Resources