I am getting a segmentation fault error when trying to sort the structure by using pointer. I guess it makes problem in 'scanf_s' function in 'main()' since "Debug MSG 2" is not printed when it is executed. here is the full code.
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct contestant
{
char *name;
float height;
int weight;
} ppl;
typedef int(*Funcptr)(ppl *, ppl *);
int namecmp(ppl *, ppl *);
int heightcmp(ppl *, ppl *);
int weightcmp(ppl *, ppl *);
void sort(Funcptr, Funcptr, Funcptr, ppl *, int);
int main()
{
int i;
int num;
ppl *people;
scanf_s("%d", &num);
people = (ppl *)malloc(num * sizeof(ppl));
printf("Debug MSG 1\n");
for (i = 0; i<num; i++)
scanf_s("%s %f %d", people[i].name, &(people[i].height), &(people[i].weight));
printf("Debug MSG 2\n");
sort(namecmp, heightcmp, weightcmp, people, num);
sort(heightcmp, weightcmp, namecmp, people, num);
sort(weightcmp, namecmp, heightcmp, people, num);
free(people);
}
int namecmp(ppl *human1, ppl *human2)
{
char *temp;
if (strcmp(human1->name, human2->name) > 0)
{
temp = human1->name;
human1->name = human2->name;
human1->name = temp;
return 1;
}
else if (strcmp(human1->name, human2->name) == 0)
return 0;
else
return -1;
}
int heightcmp(ppl *human1, ppl *human2)
{
float temp;
if (human1->height > human2->height)
{
temp = human1->height;
human1->height = human2->height;
human2->height = temp;
return 1;
}
else if (human1->height == human2->height)
return 0;
else
return -1;
}
int weightcmp(ppl *human1, ppl *human2)
{
int temp;
if (human1->weight > human2->weight)
{
temp = human1->weight;
human1->weight = human2->weight;
human2->weight = temp;
return 1;
}
else if (human1->weight > human2->weight)
return 0;
else
return -1;
}
void sort(Funcptr func1, Funcptr func2, Funcptr func3, ppl *person, int number)
{
int i, j;
int res1, res2;
for (i = 0; i<number - 1; i++)
{
for (j = i + 1; j<number; j++)
{
res1 = func1((person + i), (person + j));
if (res1 == 0)
{
res2 = func2((person + i), (person + j));
if (res2 == 0)
{
func3((person + i), (person + j));
}
}
}
}
for (i = 0; i<number; i++)
{
printf("%s %.1f %d\n", (person + i)->name, (person + i)->height, (person + i)->weight);
}
}
you're mallocing the table of people all right
people = (ppl *)malloc(num * sizeof(ppl));
(except that you don't have to cast return of malloc, but that's a detail)
but that doesn't dispense you to allocate memory for your name member structure
for (i = 0; i<num; i++)
scanf_s("%s %f %d", people[i].name, ...
Also as BLUEPIXY noticed, you're not using scanf_s properly (I thought it was scanf), you need to pass the max numbers of chars or simply use scanf with a size limitation.
fix it like that for instance:
for (i = 0; i<num; i++)
{
people[i].name = malloc(51);
scanf("%50s %f %d", people[i].name, ....
}
Alternate solution: define your structure as follows:
typedef struct contestant
{
char name[50];
float height;
int weight;
} ppl;
so no need to malloc the name. Allocating the array of ppl like you did is enough.
Related
I created a struct of student inside the function using malloc and populated it with data. I want to return the address of the array of struct back to main and print it line by line, but with my implementation, it is not printing. I debugged my code and indeed, it is able to return the address of my array to main. I don't know why it's not printing though. Any thoughts?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student Student;
struct student
{
char name[100];
int age;
char sex;
};
Student **getstudents(int n)
{
Student **t = malloc(sizeof *t * n); // memory for the array of pointers
for (int i = 0; i < n; i++) // memory for each individual pointer
{
t[i] = malloc(sizeof **t);
}
/* Data is inputted by user with form <student> <sex> <age>, then get mapped to the struct *t */
return t; /* Pointer to an array of pointers */
}
int main()
{
Student **students;
int n;
scanf("%d\n", &n);
students = getstudents(n);
for (int i = 0; i < n; i++)
{
printf("Name: %s, Sex: %s, Age: %d\n", students[i]->name, students[i]->sex, students[i]->age);
}
for (int i = 0; i < n; i++)
{
free(students[i]);
}
free(students);
return 0;
}
I am only allowed to modify the code in `Student **getstudents(int n)`.
In the line:
Student *t = (char*)malloc(sizeof(Student)*n);
You are allocating memory for one pointer, if you want to return a pointer to pointer, you need to allocate memory accordingly:
Student **t = malloc(sizeof *t * n); // memory for the array of pointers
for(int i = 0; i < n; i++){ // memory for each individual pointer
t[i] = malloc(sizeof **t);
}
To later free the pointers you also need to free each individual pointer previously allocated:
for(int i = 0; i < n; i++){ // memory for each individual pointer
free(students[i]);
}
free(students);
Note that the specifier for a single character is %c, the printf will need to be corrected:
printf("Name: %s, Sex: %c, Age: %d\n", students[i]->name, students[i]->sex, students[i]->age);
// ^^
Another thing I would change is in strncpy instead of null terminating the string later I would let the function do it:
// one more byte and strncpy terminates the string for you
strncpy(t[i]->name, data[0], strlen(data[0]) + 1);
// ^^^^
// already corrected for the new pointer
Having corrected the issues here is a possible alternative you can use to parse all the elements in the struct with sscanf from entry in one go, if you want to:
Student **getstudents(int n)
{
Student **t = malloc(sizeof *t * n); // memory for the array of pointers
if (t == NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}
for (int i = 0; i < n; i++) // memory for each individual pointer
{
t[i] = malloc(sizeof **t);
if (t[i] == NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < n; i++)
{
char entry[100];
if (fgets(entry, sizeof entry, stdin))
{
if (sscanf(entry, "%25s %c %d", t[i]->name, &t[i]->sex, &t[i]->age) != 3)
{
// deal with bad input
}
}
}
return t;
}
anastaciu answer points many troubles, but there is others :
Another problem in your code is that you use '%s' for the sex as sex is a only char. You should use %c or else the printf function will try to parse a string and will get a SEGFAULT.
I urge you too to stricly check every memory allocation. Always.
The revised code from my pov :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student Student;
struct student{
char name[100];
int age;
char sex;
};
Student **getstudents(int);
void free_students(Student**, int);
int main(){
Student **students;
int n = 4;
students = getstudents(n);
for(int i = 0; i < n; i++){
if (students[i] != NULL) {
printf("Name: %s, Sex: %c, Age: %d\n", students[i]->name, students[i]->sex, students[i]->age);
}
}
free_students(students, n);
return 0;
}
Student **getstudents(int n){
Student **t = (Student **)malloc(sizeof(Student *)*n);
if (t==NULL) {
perror("Memory: can't allocate.");
return(NULL);
}
/* Input: <name> <sex> <age> */
char entry[100];
for(int i = 0; i < n; i++){
t[i]=NULL;
if (fgets(entry,100,stdin) != NULL) {
int readBytes = strlen(entry);
char newString[3][25];
int k,j,ctr;
j=0; ctr=0;
for(k=0;k<=readBytes;k++)
{
if(entry[k]==' '||entry[k]=='\0'||entry[k]=='\n')
{
newString[ctr][j]='\0';
ctr++;
j=0;
}
else
{
newString[ctr][j]=entry[k];
j++;
}
}
t[i] = (Student *)malloc(sizeof(Student));
if (t[i] == NULL) {
perror("Memory: can't allocate.");
return(NULL);
}
strncpy(t[i]->name, newString[0], strlen(newString[0]));
t[i]->name[strlen(newString[0])] = '\0';
t[i]->sex = *newString[1];
t[i]->age = atoi(newString[2]);
}
}
return t;
}
void free_students(Student **students, int n){
for(int i=0; i<n; i++){
free(students[i]);
}
free(students);
}
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;
}
this program create a file,write on the file, after read from that file, update data and then put the file's content into an array. When I run the code, it doesn't work right, in fact, all values printed except for Vet[i].squadra are zero. I debugged the code and I saw that AggiornaFile function resets to zero variable's values each time I use fseek and freed, so I think that fwrite update values into file with zeros.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define DIMMAX 4
#define DIMCAR 20
typedef char Stringa[DIMCAR];
typedef struct{
int vinte;
int perse;
int nulle;
} Partite;
typedef struct{
int subiti;
int effettuati;
} Goal;
typedef struct{
int squadra;
Partite partite;
Goal goal;
int punti;
} Nota;
typedef struct{
int squadra1;
int squadra2;
int goal1;
int goal2;
} Match;
void CreaFile(Stringa, int);
void DisputaMatch(Match *, int, int);
void AggiornaFile(Stringa, Match);
int CalcolaEsito(Match);
void DisputaFase(int, Stringa);
Nota CalcolaClassifica(Nota[], int, Stringa);
void ordina(Nota *, int);
void StampaClassifica(Nota[], int);
int calcolaNPartite(Nota);
void CreaFile(Stringa percorso, int valDati){
FILE *ptr;
Nota n;
int i;
ptr = fopen(percorso, "wb");
if(ptr ==NULL){
printf("File inesistente.\n");
}
else{
for(i=1; i<= valDati; i++){
n.partite.vinte = 0;
n.partite.perse = 0;
n.partite.nulle = 0;
n.goal.subiti = 0;
n.goal.effettuati = 0;
n.punti = 0;
n.squadra = i;
fwrite(&n, sizeof(Nota), 1, ptr);
}
fclose(ptr);
}
}
void DisputaMatch(Match *incontro, int S1, int S2){
int rand1,rand2;
incontro->squadra1 = S1;
incontro->squadra2 = S2;
rand1 = rand() % 5;
rand2 = rand() % 5;
incontro->goal1 = rand1;
incontro->goal2 = rand2;
}
void AggiornaFile(Stringa percorso, Match incontro){
FILE *ptr;
Nota n;
int esito;
ptr = fopen(percorso, "rb+");
if(ptr == NULL){
printf("File inesistente.\n");
}
else{
fseek(ptr, incontro.squadra1*sizeof(Nota), SEEK_SET);
fread(&n, sizeof(Nota), 1, ptr);
n.goal.effettuati += incontro.goal1;
n.goal.subiti += incontro.goal2;
esito = CalcolaEsito(incontro);
switch(esito){
case 0:
n.partite.nulle++;
n.punti += 1;
break;
case 1:
n.partite.vinte++;
n.punti += 3;
break;
case 2:
n.partite.perse++;
break;
}
fwrite(&n, sizeof(Nota),1, ptr);
fseek(ptr, incontro.squadra2*sizeof(Nota), SEEK_SET);
fread(&n, sizeof(Nota), 1, ptr);
n.goal.effettuati += incontro.goal2;
n.goal.subiti += incontro.goal1;
switch(esito){
case 0:
n.partite.nulle++;
n.punti += 1;
break;
case 1:
n.partite.perse++;
break;
case 2:
n.partite.vinte++;
n.punti += 3;
break;
}
fwrite(&n, sizeof(Nota),1, ptr);
fclose(ptr);
}
}
int CalcolaEsito(Match incontro){
int esito;
if(incontro.goal1 == incontro.goal2){
esito = 0;
}
else if(incontro.goal1 > incontro.goal2){
esito = 1;
}
else{
esito = 2;
}
return esito;
}
void DisputaFase(int valDati, Stringa percorso){
Match incontro;
int i,j;
for(i=1; i<=valDati; i++){
for(j=1; j<=valDati; j++){
if( j!= i){
DisputaMatch(&incontro, i, j);
AggiornaFile(percorso, incontro);
}
}
}
}
Nota CalcolaClassifica(Nota Vet[], int dim, Stringa percorso){
FILE *ptr;
Nota n;
int i = 0;
ptr = fopen(percorso, "rb");
if(ptr == NULL){
printf("File inesistente.\n");
}
else{
while(!feof(ptr)){
fread(&n, sizeof(Nota),1,ptr);
Vet[i] = n;
i++;
}
fclose(ptr);
}
ordina(Vet, dim);
return Vet[0];
}
void ordina(Nota *Vet, int dim){
int i,j;
int min;
Nota temp;
for(i=0; i<dim-1; i++){
min = i;
for(j=i+1; j<dim; j++){
if(Vet[min].punti < Vet[j].punti){
min = j;
}
}
if(min != i){
temp = Vet[min];
Vet[min] = Vet[i];
Vet[i] =temp;
}
}
}
void StampaClassifica(Nota Vet[], int dim){
int i,j;
printf("\n%s%15s%15s%18s%15s%15s%15s%15s\n", "Squadra", "Punteggio", " PartiteGiocate", "Vinte", "Perse", "Nulle", "Gsubiti", "Gfatti");
for(i=0; i<dim; i++){
printf("%7d%15d%15d%18d%15d%15d%15d%15d\n", Vet[i].squadra, Vet[i].punti, calcolaNPartite(Vet[i]), Vet[i].partite.vinte, Vet[i].partite.perse, Vet[i].partite.nulle,Vet[i].goal.subiti, Vet[i].goal.effettuati);
}
}
int calcolaNPartite(Nota nota){
int giocate;
giocate = nota.partite.nulle + nota.partite.perse + nota.partite.vinte;
return giocate;
}
int main(int argc, char *argv[]) {
FILE *ptr;
char percorso[300] = "C:\\file.dat";
Nota Vet[DIMMAX];
srand(time(NULL));
CreaFile(percorso, DIMMAX);
DisputaFase(DIMMAX, percorso);
CalcolaClassifica(Vet, DIMMAX, percorso);
StampaClassifica(Vet, DIMMAX);
return 0;
}
Note that fread and fwrite both advance the file pointer.
When wanting to read/modify/write in AggiornaFile you must fseek again before the write.
Also, be sure to use 0-based record indexing.
I am trying to work through my code, I'm unable to use a sorting algorithm due to crashes caused by trying to copy a structure at a specific array position to another in the same array at a different location.
//include statements
#include <stdio.h>
#include <stdlib.h>
//defines
#define MAX 100
#define STRUCTMAX 26
#define STUDENTS 9
//Struct declarations
typedef struct{
char street[STRUCTMAX];
char city[STRUCTMAX];
char state[STRUCTMAX];
char zip[STRUCTMAX];
}Address;
typedef struct{
char firstName[STRUCTMAX];
char initial[STRUCTMAX];
char lastName[STRUCTMAX];
Address adress;
int age;
double gpa;
}Student;
//prototypes
void readFile(Student students[]);
void printAll(Student students[]);
void printBestGpaName(Student students[]);
double averageGPA(Student students[]);
void printAboveAverageGPA(Student students[]);
void printYoungestLowGPA(Student students[]);
void sortStruct(Student students[]);
void strSub(char s1 [], char s2 [], int start, int size);
void initialize(Student students[]);
void main(void){
Student students[STUDENTS];
readFile(students);
printAll(students);
printBestGpaName(students);
printf("Average G.P.A is %.2lf\n" ,averageGPA(students));
printAboveAverageGPA(students);
printYoungestLowGPA(students);
sortStruct(students);
printf("\n");
printAll(students);
}
void readFile(Student students[]){
int i = 0;
char numberValue[10];
char line[MAX];
FILE *fp;
fp = fopen(
"/Users/derekroy/Desktop/Lab_6/Lab_6A/Students.dat", "r");
if (fp == NULL) {
printf("Students.dat file not found.\n");
exit(1);
}
while (!feof(fp)) {
fgets(line, MAX, fp);
strSub(line, students[i].firstName, 0, 7);
strSub(line, students[i].initial, 10, 1);
strSub(line, students[i].lastName, 11, 9);
strSub(line, students[i].adress.street, 20, 16);
strSub(line, students[i].adress.city, 36, 13);
strSub(line, students[i].adress.state, 49, 2);
strSub(line, students[i].adress.zip, 52, 5);
strSub(line, numberValue, 58, 2);
students[i].age = atoi(numberValue);
strSub(line, numberValue, 60, 5);
students[i].gpa = atof(numberValue);
i++;
}
}
void printAll(Student students[]){
int i;
printf("All listed Students: \n");
for(i = 0; i < STUDENTS; ++i){
printf("%s %s %s %s %s %s, %s %d %.2lf\n" , students[i].firstName, students[i].initial,
students[i].lastName, students[i].adress.street, students[i].adress.city,
students[i].adress.state, students[i].adress.zip, students[i].age, students[i].gpa);
}
printf("\n");
printf("******");
}
void printBestGpaName(Student students[]){
int i, best = 0;
for(i = 0; i < STUDENTS; ++i){
if(students[i].gpa > students[best].gpa)
best = i;
}
printf("Student with best G.P.A: ");
printf("%s %s %s\n" , students[best].firstName, students[best].initial, students[best].lastName);
}
double averageGPA(Student students[]){
int i;
double sum = 0.0;
for(i = 0; i < STUDENTS; ++i){
sum += students[i].gpa;
}
return sum / i;
}
void printAboveAverageGPA(Student students[]){
int i;
double average = averageGPA(students);
printf("Students with above average G.P.A: \n");
for(i = 0; i < STUDENTS; ++i){
if(students[i].gpa > average)
printf("%s %s %s\n" , students[i].firstName, students[i].initial, students[i].lastName);
}
}
void printYoungestLowGPA(Student students[]){
int i, j, young = 1000;
double average = averageGPA(students);
for(i = 0; i < STUDENTS; ++i){
if(students[i].gpa < average){
if(students[i].age < young){
j = i;
young = students[i].age;
}
}
}
printf("The youngest student with a below average G.P.A: ");
printf("%s %s %s\n" ,students[j].firstName, students[j].initial, students[j].lastName);
}
void sortStruct(Student students[]){
int i, j;
Student temp;
for(i = 1; i < STRUCTMAX; ++i){
/*temp.firstName = students[i].firstName;
temp.initial = students[i].initial;
temp.lastName = students[i].lastName;
temp.adress.street = students[i].adress.street;
temp.adress.city = students[i].adress.city;
temp.adress.state = students[i].adress.state;
temp.adress.zip = students[i].adress.zip;
temp.age = students[i].age;
temp.gpa = students[i].gpa;*/
temp = students[i];
j = i - 1;
while(j >= 0 && temp.gpa < students[j].gpa){
//students[j+1] = students[j];
j = j - 1;
}
//students[j+1] = temp;
}
}
void strSub(char s1 [], char s2 [], int start, int size){
int i;
for(i = 0; i < size; ++i){
s2[i] = s1[start];
start++;
}
s2[i] = '\0';
}
The offending line is in the Sort function.
How can I make this work, and copy the specified structure to their new address in the structure array?
you defined only 9 student records
Student students[STUDENTS]; -> STUDENTS macro is 9
you are iterating till STRUCTMAX which is a macro defined as 26
so you will go out of bounds causing the crash
for(i = 1; i < STRUCTMAX; ++i){
#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