I'm writing a program in C and I'm aware you have to allocate appropriate space for efficient code but am unsure of how to start, I've written and completed my program and it would be a shame to restart. If anyone can guide me how to properly malloc space for my program it would be appreciated.
Here is my code as follows:
main.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "courses.h"
int main (int argc, char *argv[]) {
srand (time(NULL));
createStudents ();
createCourses ();
regiserStudents ();
printCourses ();
return 1;
}
courses.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "structs.h"
void createStudents () {
int random, i;
for (i = 0; i < 12; i++) {
students[i].firstName = *firstName[i];
students[i].lastName = *lastName[i];
random = 10000 + rand() % 89999;
students[i].num.studentNum = random;
printf("%d - %s, %s \n", students[i].num.studentNum, students[i].lastName, students[i].firstName);
}
}
void createCourses () {
int numbers[999];
int numbersLeft = 999;
char courseCode[512];
int numCourses = 3;
int random, i, j;
for (i = 0; i < 999; i++) {
numbers[i] = i;
}
for (j = 0; j < numCourses; j++) {
random = rand() % numbersLeft;
if (random < 10) {
snprintf(courseCode, sizeof courseCode, "CS00%d", random);
}
else if (random < 100 && random > 9) {
snprintf(courseCode, sizeof courseCode, "CS0%d", random);
}
else {
snprintf(courseCode, sizeof courseCode, "CS%d", random);
}
courses[j].cName = courseName[j];
courses[j].cDescription = courseDescription[j];
courses[j].cCode = courseCode;
numbers[random] = numbers[numbersLeft-1];
numbersLeft--;
random = 4 + rand() % 4;
courses[j].maxRegister = random;
}
}
void regiserStudents () {
int checkSum = 0, checkSum1 = 0, checkTemp = 0, count0 = 0, count1 = 0, count2 = 0;
int v, i, j, random;
for (i = 0; i < 2; i++) {
checkTemp = count0;
for (j = 0; j < 12; j++) {
random = rand() % 3;
if (random == 0) {
if (count0 == 0) {
courses[random].registered[count0] = &students[j];
count0++;
}
else {
checkSum1 = students[j].num.studentNum;
for (v = 0; v < checkTemp; v++) {
checkSum = courses[0].registered[v]->num.studentNum;
if (checkSum == checkSum1) {
/*Do Nothing*/
}
else {
courses[random].registered[count0] = &students[j];
count0++;
}
}
}
}
if (random == 1) {
if (count1 == 0) {
courses[random].registered[count1] = &students[j];
count1++;
}
else {
checkSum1 = students[j].num.studentNum;
for (v = 0; v < checkTemp; v++) {
checkSum = courses[1].registered[v]->num.studentNum;
if (checkSum == checkSum1) {
/*Do Nothing*/
}
else {
courses[random].registered[count1] = &students[j];
count1++;
}
}
}
}
if (random == 2) {
if (count2 == 0) {
courses[random].registered[count2] = &students[j];
count2++;
}
else {
checkSum1 = students[j].num.studentNum;
for (v = 0; v < checkTemp; v++) {
checkSum = courses[2].registered[v]->num.studentNum;
if (checkSum == checkSum1) {
/*Do Nothing*/
}
else {
courses[random].registered[count2] = &students[j];
count2++;
}
}
}
}
}
}
courses[0].studentRegistered = count0;
courses[1].studentRegistered = count1;
courses[2].studentRegistered = count2;
}
void printCourses () {
int i;
printf("\n%s - %s\n%s\nRegistered Students (%d/%d):\n", courses[0].cCode, courses[0].cName, courses[0].cDescription, courses[0].studentRegistered, courses[0].maxRegister);
for (i = 0; i < courses[0].studentRegistered; i++) {
printf("%d - %s, %s \n", courses[0].registered[i]->num.studentNum, courses[0].registered[i]->lastName, courses[0].registered[i]->firstName);
}
printf("\n%s - %s\n%s\nRegistered Students (%d/%d):\n", courses[1].cCode, courses[1].cName, courses[1].cDescription, courses[1].studentRegistered, courses[1].maxRegister);
for (i = 0; i < courses[1].studentRegistered; i++) {
printf("%d - %s, %s \n", courses[1].registered[i]->num.studentNum, courses[1].registered[i]->lastName, courses[1].registered[i]->firstName);
}
printf("\n%s - %s\n%s\nRegistered Students (%d/%d):\n", courses[2].cCode, courses[2].cName, courses[2].cDescription, courses[2].studentRegistered, courses[2].maxRegister);
for (i = 0; i < courses[2].studentRegistered; i++) {
printf("%d - %s, %s \n", courses[2].registered[i]->num.studentNum, courses[2].registered[i]->lastName, courses[2].registered[i]->firstName);
}
}
courses.h
#ifndef COURSES_H_
#define COURSES_H_
void createStudents();
void createCourses ();
void regiserStudents ();
void printCourses ();
#endif
structs.h
#ifndef STRUCTS_H_
#define STRUCTS_H_
char *firstName[] = {
"Emma", "Liam", "Olivia",
"Noah", "Ava", "Logan",
"Sophia", "Lucas", "Isabella",
"Mason", "Shaylyn", "Jack"
};
char *lastName[] = {
"Smith", "Johnson", "Williams",
"Brown", "Jones", "Miller",
"Davis", "Garcia", "Rodriguez",
"Wilson", "Seguin", "Loveday"
};
typedef struct{
int studentNum;
}studentNumber;
typedef struct{
char *firstName;
char *lastName;
studentNumber num;
}studentID;
studentID students[12];
char *courseName[] = {"Web Programming", "Technical Communication", "Processor Architecture"};
char *courseDescription[] = {"Learn to make websites!", "Learn the essentials of communication skills", "Learn the basics of circuits and Machine Language coding"};
typedef struct {
int maxRegister;
char *cCode;
char *cName;
char *cDescription;
studentID *registered[8];
studentID *waitlisted[12];
int studentRegistered;
int studentWaitlisted;
}course;
course courses[3];
#endif
Essentially the program should run as: create students, create random school courses, fill the students into the courses, and then print everything while accessing the structs from a header file (structs.h)
Here's the message I receive of running the program after it compiles:
Segmentation fault (core dumped)
In createStudents(), you don't need to dereference firstName[i] nor lastName[i]:
students[i].firstName = *firstName[i];
students[i].lastName = *lastName[i];
Since firstName[i] already gives you a char *, you can assign that pointer directly to students[i].firstName (same goes for lastName):
students[i].firstName = firstName[i];
students[i].lastName = lastName[i];
Related
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <mpi.h>
#define MaxSize 50
typedef int ElementType;
typedef int Position;
typedef int Status;
typedef struct SeqStack
{
ElementType Data[MaxSize];
Position Top;
int (*Push)(struct SeqStack *L);
int (*Pop)(struct SeqStack *L , int e);
int (*isEmpty)(struct SeqStack s);
Status (*isFull)(struct SeqStack s);
}SeqStack;
int Push(SeqStack *L)
{
if(L->Top == 0)
{
return 0;
}
printf("%d ",L->Data[--L->Top]);
return 1;
}
int Pop(SeqStack *L , int e)
{
if(L->Top==MaxSize -1)
{
return 0;
}
L->Data[L->Top++] = e;
return 1;
}
int isEmpty(SeqStack s)
{
if(s.Top != 0)
{
return 1;
}
return 0;
}
Status isFull(SeqStack s)
{
if(s.Top != MaxSize -1)
{
return 1;
}
return 0;
}
int global_max;
int ans = INT_MAX;
void *tsp(int Dis[global_max][global_max],int v[],int N,int count,int currPos,int cost,int sum,int* result,int temp[],int make_log){
temp[0]=1;
//int mode;
//printf("count:%d\n",count);
if(count == N&&Dis[currPos][1]>0){
//printf("Ans:%d,cost:%d\n",ans,cost);
if(make_log == 1){
char str[100]={'\0'};
char output[100]={'\0'};
//printf("Ans:%d,cost:%d\n",ans,cost);
FILE *log;
for(int i=0; i<N;i++){
if (i!=N-1){
sprintf(str,"%d",temp[i]);
strcat(output,str);
strcat(output,",");
}else{
sprintf(str,"%d",temp[i]);
strcat(output,str);
strcat(output,"=");
}
}
sprintf(str,"%d",cost);
strcat(output,str);
strcat(output,"\n");
log=fopen("log.txt","a");
fputs(output,log);
fclose(log);
}
if(sum> cost){
sum = cost;
ans = cost;
//printf("every ans is %d\n\n\n\n",ans);
for (int i=0;i<N;i++){
//printf("temp[%d]=%d,",i,temp[i]);
result[i]=temp[i];
//printf("result[%d]=%d,",i,result[i]);
}
}
//ans = min(ans,cost + Dis[1][currPos]);
return result;
}
for (int i = 1;i<N+1;i++){
//printf("!!!!!!! v[%d] = %d\n",i,v[i]);
if(v[i]==0&&Dis[currPos][i]>0){
//printf("cost + Dis: %d + %d\n",cost,Dis[currPos][i]);
if(cost + Dis[currPos][i] <= ans||count==N-1){
v[i] = 1;
temp[count] = i;
//printf("\ntemp[%d] = %d\n",count,temp[count]);
//printf("currPos:%d,i:%d,count:%d\n",currPos,i,count);
//printf("Ans:%d,cost:%d\n",ans,cost);
result = tsp(Dis,v,N,count + 1,i,cost + Dis[currPos][i],sum,result,temp,make_log);
//mode = 0;
v[i]= 0;
if(count==1){
for(int j = 2;j<N+1;j++){
v[j]= 0;
}
}
}else{
//printf("currPos:%d,i:%d,count:%d\n",currPos,i,count);
temp[count] = i;
for (int k = N-1;k>count;k--){
temp[k] = 0;
}
int v_copy[N];
for (int o = 1;o<N+1;o++){
v_copy[o] = v[o];
// if(currPos==3&&i==4){
// printf("v_copy[%d] = %d//",o,v_copy[o]);
// }
}
for(int j = 2;j< N + 1;j++){
if(v[j]==0){
v[j] = 1;
}
}
result = tsp(Dis,v,N,N,N,cost + Dis[currPos][i],sum,result,temp,make_log);
//printf("Fuck currpos:%d\n",currPos);
for (int o = 1;o<N+1;o++){
v[o] = v_copy[o];
// if(currPos==3&&i==2){
// printf("v[%d] = %d//",o,v[o]);
// }
}
if(count==1){
for(int j = 2;j<N+1;j++){
v[j]= 0;
}
}
}
}
}
return result;
};
void change(int n){
global_max = n;
};
int main(int argc, char const *argv[])
{
int N;
int size = 1;
int count = 1;
int log = 0;
int nthreads,my_rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nthreads);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if(argc > 2){
log = 1;
}
char x[100] = {0};
char filename[100] = {};
strcat(filename,argv[1]);
strcat(filename,".txt");
//printf("%s\n",filename);
FILE *fp=fopen(filename,"r");
if(fp==NULL){
printf("Cannot open the file,strike any key to exit!\n");
getchar();
exit(0);
}
for (int i = 0;!feof(fp);i++){
fscanf(fp,"%hhd",&x[i]);
}
N=x[0];
change(N);
int* result;
result = (int *)malloc(sizeof(int) * global_max);
int Dis[N][N], City[N];
for(int i=1;i<N;i++){
size=size*i;
}
char y[size];
for (int i=1;i<size+1;i++){
y[i] = x[i];
//printf("%d\n",y[i]);
}
for(int i=2; i < N + 1; i++){
for(int j=1; j < i ; j++){
Dis[j][i] = y[count];
Dis[i][j] = y[count];
count+=1;
//printf("(%d,%d),(%d,%d)",j,i,i,j);
//printf("%d\n",Dis[j][i]);
}
}
for(int i=0;i<N;i++){
City[i]=i + 1;//create the number of city with 1 ...... N
}
int curr_constraint = 0;
int v[N+1];
for (int i = 1; i < N+1; i++){
v[i] = 0;
}
for(int i = 1;i<N+1;i++){
curr_constraint += Dis[i][i+1];
}
v[1]= 1;
int sum = INT_MAX;
//printf("orginal ans is %d\n",ans);
//printf("Dis map:\n");
for( int i= 1;i<N+1;i++){
for(int j =1;j<N+1;j++){
if(i==j){
Dis[i][j]=0;
}
//printf("%d ",Dis[i][j]);
}
//printf("\n");
}
//printf("The orginal constraint is %d\n",curr_constraint);
int temp[N];
int* city_divided;
int cityNumber;
int current_ans;
SeqStack s;
if(nthreads > 1){
int remain = N % (nthreads - 1);
//int group_n = N /(nthreads - 1);
if(remain !=0){
if(my_rank <= remain && my_rank != 0){
cityNumber = ((N - remain)/(nthreads - 1)) + 1;
city_divided = (int*)malloc(cityNumber*sizeof(int));
for (int i = 0; i <cityNumber; i++)
{
city_divided[i] = City[(my_rank-1)*cityNumber + 1];
}
}else{
cityNumber = ((N - remain) / (nthreads - 1));
city_divided = (int*)malloc(cityNumber*sizeof(int));
for (int i = 0; i <cityNumber; i++)
{
city_divided[i] = City[(my_rank-1)*cityNumber + 1];
}
}
}else{
cityNumber = N / (nthreads - 1);
city_divided = (int*)malloc(cityNumber*sizeof(int));
for (int i = 0; i <cityNumber; i++)
{
city_divided[i] = City[(my_rank-1)*cityNumber + 1];
}
}
if(my_rank==0){
MPI_Recv(&ans, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for(int i=0;i<N;i++){
if(i != N-1){
printf("%d,",*(result+i));
}
else{
printf("%d",*(result+i));
}
}
printf("\n");
printf("Distance: %d\n",ans);
}
if(my_rank!=0){
for (int i = 0 ; i<cityNumber;i++){
current_ans = ans;
while(s.isEmpty(s)){
MPI_Recv(&ans, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
result = tsp(Dis,v,N,1,city_divided[i],0,ans,result,temp,log);
s.Pop(&s,ans);
}
result = tsp(Dis,v,N,1,city_divided[i],0,ans,result,temp,log);
if(current_ans - ans > 0){
s.Push(ans);
MPI_Bcast(&ans,1,MPI_INT,0,MPI_COMM_WORLD);
}
}
}
}
else{
result = tsp(Dis,v,N,1,1,0,sum,result,temp,log);
}
for(int i=0;i<N;i++){
if(i != N-1){
printf("%d,",*(result+i));
}
else{
printf("%d",*(result+i));
}
}
printf("\n");
printf("Distance: %d\n",ans);
return 0;
}
I am trying to solve a special travelling salesman problem with mpi and c. I want make the master processor print the final information including the route and the shorest distance. the other processors with all city group run the tsp function, and when it has the shorter distance, use mpi_send or mpi_Bcast to other processors.Follow this logic, I meet a problem when I run the program.
enter image description here
I am trying to sort an array of structures of size 5500 using merge sort.
However, I am getting a segmentation fault pretty quickly because I am not allowed to use VLA. so I have to create 2 extra arrays of size 5500 each time I call merge-sort recursively.
I would appreciate a fix for my problem. I will provide my code here:
void merge(Student rightArr[], Student leftArr[], Student mergedArr[], int sizeOfRight, int sizeOfLeft) {
int rightArrIndex = 0;
int leftArrIndex = 0;
int mergedArrIndex = 0;
while (leftArrIndex < sizeOfLeft && rightArrIndex < sizeOfRight) {
char *ptrLeft, *ptrRight;
long gradeLeft = strtol(leftArr[leftArrIndex].grade, &ptrLeft, BASE_COUNT);
long gradeRight = strtol(rightArr[rightArrIndex].grade, &ptrRight, BASE_COUNT);
if (gradeLeft > gradeRight) {
mergedArr[mergedArrIndex] = rightArr[rightArrIndex];
rightArrIndex++;
} else {
mergedArr[mergedArrIndex] = leftArr[leftArrIndex];
leftArrIndex++;
}
mergedArrIndex++;
}
if (leftArrIndex == sizeOfLeft) {
for (int i = mergedArrIndex; i < (sizeOfLeft + sizeOfRight); i++) {
mergedArr[i] = rightArr[rightArrIndex];
rightArr++;
}
} else {
for (int i = mergedArrIndex; i < (sizeOfLeft + sizeOfRight); i++) {
mergedArr[i] = leftArr[leftArrIndex];
leftArr++;
}
}
}
void mergeSort(Student studentsArray[], int amountOfStudents) {
if (amountOfStudents <= 1) {
return;
}
int leftSize = (amountOfStudents / 2);
int rightSize = (amountOfStudents - leftSize);
Student leftArr[5500], rightArr[5500];
for (int i = 0; i < leftSize; i++) {
leftArr[i] = studentsArray[i];
}
for (int i = 0; i < rightSize; i++) {
rightArr[i] = studentsArray[i + leftSize];
}
mergeSort(leftArr, leftSize);
mergeSort(rightArr, rightSize);
merge(rightArr, leftArr, studentsArray, rightSize, leftSize);
}
Ok, I think this should do what you want. It assumes that Student and BASE_COUNT have been defined:
#include <stdlib.h>
#include <stdio.h>
void merge(Student studentsArr[],
int leftSize, int rightSize,
Student scratchArr[])
{
Student *leftArr = studentsArr;
Student *rightArr = studentsArr + leftSize;
int leftIx = 0, rightIx = 0, mergeIx = 0, ix;
while (leftIx < leftSize && rightIx < rightSize) {
long gradeLeft = strtol(leftArr[leftIx].grade, NULL, BASE_COUNT);
long gradeRight = strtol(rightArr[rightIx].grade, NULL, BASE_COUNT);
if (gradeLeft <= gradeRight) {
scratchArr[mergeIx++] = leftArr[leftIx++];
}
else {
scratchArr[mergeIx++] = rightArr[rightIx++];
}
}
while (leftIx < leftSize) {
scratchArr[mergeIx++] = leftArr[leftIx++];
}
// Copy the merged values from scratchArr back to studentsArr.
// The remaining values from rightArr (if any) are already in
// their proper place at the end of studentsArr, so we stop
// copying when we reach that point.
for (ix = 0; ix < mergeIx; ix++) {
studentsArr[ix] = scratchArr[ix];
}
}
void mergeSortInternal(Student studentsArray[],
int amountOfStudents,
Student scratchArr[])
{
if (amountOfStudents <= 1) {
return;
}
int leftSize = amountOfStudents / 2;
int rightSize = amountOfStudents - leftSize;
mergeSortInternal(studentsArray, leftSize, scratchArr);
mergeSortInternal(studentsArray + leftSize, rightSize, scratchArr);
merge(studentsArray, leftSize, rightSize, scratchArr);
}
#define MAX_ARR_SIZE 5500
void mergeSort(Student studentsArray[], int amountOfStudents)
{
if (amountOfStudents <= 1) {
return;
}
if (amountOfStudents > MAX_ARR_SIZE) {
fprintf(stderr, "Array too large to sort.\n");
return;
}
Student scratchArr[MAX_ARR_SIZE];
mergeSortInternal(studentsArray, amountOfStudents, scratchArr);
}
The top-level sort function is mergeSort, defined as in the original post. It declares a single scratch array of size MAX_ARR_SIZE, defined as 5500. The top-level function is not itself recursive, so this scratch array is only allocated once.
Edit: added the rest of my code so it's easier to see
I'm receiving a segmentation fault when trying to access certain values of a struct in a header file.
Here's courses.c:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "structs.h"
void createStudents () {
int random, i;
for (i = 0; i < 12; i++) {
students[i].firstName = firstName[i];
students[i].lastName = lastName[i];
random = 10000 + rand() % 89999;
students[i].num.studentNum = random;
printf("%d - %s, %s \n", students[i].num.studentNum, students[i].lastName, students[i].firstName);
}
}
void createCourses () {
int numbers[999];
int numbersLeft = 999;
char courseCode[512];
char courseCode1[512];
char courseCode2[512];
int numCourses = 3;
int random, i, j;
for (i = 0; i < 999; i++) {
numbers[i] = i;
}
for (j = 0; j < 1; j++) {
random = rand() % numbersLeft;
if (random < 10) {
snprintf(courseCode, sizeof courseCode, "CS00%d", random);
courses[0].cCode = courseCode;
}
else if (random < 100 && random > 9) {
snprintf(courseCode, sizeof courseCode, "CS0%d", random);
courses[0].cCode = courseCode;
}
else if (random > 99){
snprintf(courseCode, sizeof courseCode, "CS%d", random);
courses[0].cCode = courseCode;
}
courses[0].cName = courseName[0];
courses[0].cDescription = courseDescription[0];
numbers[random] = numbers[numbersLeft-1];
numbersLeft--;
random = 4 + rand() % 4;
courses[0].maxRegister = random;
}
for (j = 0; j < 1; j++) {
random = rand() % numbersLeft;
if (random < 10) {
snprintf(courseCode1, sizeof courseCode1, "CS00%d", random);
courses[1].cCode = courseCode1;
}
else if (random < 100 && random > 9) {
snprintf(courseCode1, sizeof courseCode1, "CS0%d", random);
courses[1].cCode = courseCode1;
}
else if (random > 99){
snprintf(courseCode1, sizeof courseCode1, "CS%d", random);
courses[1].cCode = courseCode1;
}
courses[1].cName = courseName[1];
courses[1].cDescription = courseDescription[1];
numbers[random] = numbers[numbersLeft-1];
numbersLeft--;
random = 4 + rand() % 4;
courses[1].maxRegister = random;
}
for (j = 0; j < 1; j++) {
random = rand() % numbersLeft;
if (random < 10) {
snprintf(courseCode2, sizeof courseCode2, "CS00%d", random);
courses[2].cCode = courseCode2;
}
else if (random < 100 && random > 9) {
snprintf(courseCode2, sizeof courseCode2, "CS0%d", random);
courses[2].cCode = courseCode2;
}
else if (random > 99){
snprintf(courseCode2, sizeof courseCode2, "CS%d", random);
courses[2].cCode = courseCode2;
}
courses[2].cName = courseName[2];
courses[2].cDescription = courseDescription[2];
numbers[random] = numbers[numbersLeft-1];
numbersLeft--;
random = 4 + rand() % 4;
courses[2].maxRegister = random;
}
}
void regiserStudents () {
int checkSum = 0, checkSum1 = 0, checkTemp = 0, count0 = 0, count1 = 0, count2 = 0;
int wCount0 = 0, wCount1 = 0, wCount2 = 0;
int v, i, j, random, max0, max1, max2;
max0 = courses[0].maxRegister;
max1 = courses[1].maxRegister;
max2 = courses[2].maxRegister;
for (i = 0; i < 2; i++) {
checkTemp = count0;
for (j = 0; j < 12; j++) {
random = rand() % 3;
if (random == 0) {
if (count0 == 0) {
courses[random].registered[count0] = &students[j];
count0++;
}
else {
checkSum1 = students[j].num.studentNum;
for (v = 0; v < checkTemp; v++) {
checkSum = courses[0].registered[v]->num.studentNum;
if (checkSum == checkSum1) {
/*Do Nothing*/
}
else if (count0 == max0) {
courses[random].waitlisted[count0] = &students[j];
wCount0++;
}
else {
courses[random].registered[count0] = &students[j];
count0++;
}
/*}*/
}
}
}
if (random == 1) {
if (count1 == 0) {
courses[random].registered[count1] = &students[j];
count1++;
}
else {
checkSum1 = students[j].num.studentNum;
for (v = 0; v < checkTemp; v++) {
checkSum = courses[1].registered[v]->num.studentNum;
if (checkSum == checkSum1) {
/*Do Nothing*/
}
else if (count1 == max1) {
courses[random].waitlisted[count1] = &students[j];
wCount1++;
}
else {
courses[random].registered[count1] = &students[j];
count1++;
}
}
}
}
if (random == 2) {
if (count2 == 0) {
courses[random].registered[count2] = &students[j];
count2++;
}
else {
checkSum1 = students[j].num.studentNum;
for (v = 0; v < checkTemp; v++) {
checkSum = courses[2].registered[v]->num.studentNum;
if (checkSum == checkSum1) {
/*Do Nothing*/
}
else if (count2 == max2) {
courses[random].waitlisted[count2] = &students[j];
wCount2++;
}
else {
courses[random].registered[count2] = &students[j];
count2++;
}
}
}
}
}
}
courses[0].studentRegistered = count0;
courses[1].studentRegistered = count1;
courses[2].studentRegistered = count2;
courses[0].studentWaitlisted = wCount0;
courses[1].studentWaitlisted = wCount1;
courses[2].studentWaitlisted = wCount2;
}
void printCourses () {
int i;
printf("\n%s - %s: %s\nRegistered Students (%d/%d):\n", courses[0].cCode, courses[0].cName, courses[0].cDescription, courses[0].studentRegistered, courses[0].maxRegister);
for (i = 0; i < courses[0].studentRegistered; i++) {
printf("* %d - %s, %s \n", courses[0].registered[i]->num.studentNum, courses[0].registered[i]->lastName, courses[0].registered[i]->firstName);
}
printf("Waitlisted Students (%d)", courses[0].studentWaitlisted);
if (courses[0].studentWaitlisted == 0) {
printf("\n");
}
else {
for (i = 0; i < courses[0].studentWaitlisted; i++) {
printf("* %d - %s, %s \n", courses[0].waitlisted[i]->num.studentNum, courses[0].waitlisted[i]->lastName, courses[0].waitlisted[i]->firstName);
}
}
printf("\n%s - %s: %s\nRegistered Students (%d/%d):\n", courses[1].cCode, courses[1].cName, courses[1].cDescription, courses[1].studentRegistered, courses[1].maxRegister);
for (i = 0; i < courses[1].studentRegistered; i++) {
printf("* %d - %s, %s \n", courses[1].registered[i]->num.studentNum, courses[1].registered[i]->lastName, courses[1].registered[i]->firstName);
}
printf("\n%s - %s: %s\nRegistered Students (%d/%d):\n", courses[2].cCode, courses[2].cName, courses[2].cDescription, courses[2].studentRegistered, courses[2].maxRegister);
for (i = 0; i < courses[2].studentRegistered; i++) {
printf("* %d - %s, %s \n", courses[2].registered[i]->num.studentNum, courses[2].registered[i]->lastName, courses[2].registered[i]->firstName);
}
}
And here's my header file
structs.h
#ifndef STRUCTS_H_
#define STRUCTS_H_
char *firstName[] = {
"Emma", "Liam", "Olivia",
"Noah", "Ava", "Logan",
"Sophia", "Lucas", "Isabella",
"Mason", "Shaylyn", "Jack"
};
char *lastName[] = {
"Smith", "Johnson", "Williams",
"Brown", "Jones", "Miller",
"Davis", "Garcia", "Rodriguez",
"Wilson", "Seguin", "Loveday"
};
typedef struct{
int studentNum;
}studentNumber;
typedef struct{
char *firstName;
char *lastName;
studentNumber num;
}studentID;
studentID students[12];
char *courseName[] = {"Web Programming", "Technical Communication", "Processor Architecture"};
char *courseDescription[] = {"Learn the language of HTML, and how to create websites.", "Learn the essentials of communication skills, and how to apply them on the job.", "Learn the basics of circuits and Machine Language coding."};
typedef struct {
int maxRegister;
char *cCode;
char *cName;
char *cDescription;
studentID *registered[8];
studentID *waitlisted[12];
int studentRegistered;
int studentWaitlisted;
}course;
course courses[3];
#endif
Printing the values of the registered students works fine, but when I print the waitlisted students I get a segmentation error. I used gdb and found it was on this line but couldn't figure out why:
printf("%d - %s, %s \n", courses[0].waitlisted[i]->num.studentNum, courses[0].waitlisted[i]->lastName, courses[0].waitlisted[i]->firstName);
studentID *waitlisted[12]; That means they will hold the address of variable of type structure studentID. You simply didn't do this but start to access those pointer variables. You have passed them to scanf which invokes undefined behavior due to trying to read an unintialized pointer variable.
So what you need to do here -
courses[i].waitlisted = malloc(sizeof *courses[i].waitlisted * courses[i].studentWaitlisted);
Same goes for the studentID also. Here fistName is a char* you need to allocate some meory to access it otherwise it's UB.
Or
typedef struct{
char firstName[100]; //you are considering that name length would be 100
//at max.
char lastName[100];
studentNumber num;
}studentID;
After OP edited question:
The seg fault you get is because of accessing a local variable after it's lifetime ended.
courses[0].cCode = courseCode;
What you can do is
courses[0].cCode = strdup(courseCode);
Initialize array int numbers[999]={0}; otherwise you might access garbage value as the indexing is result of random number geneartion.
if( random < 999){
numbers[random] = numbers[numbersLeft-1];
numbersLeft--;
}
else{
fprintf(stderr, "%s\n","Error" );
}
Lots of repeated code. You should remove repeated code. And also there is no need for single-iteration-for-loop.
The user is supposed to be prompted with several letters that they are to decode and then input their word which returns a score for that word.
I can get the program to compile but the program does not actually run. So I am not entirely sure where the issue lies within my code.I am relatively new at this.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
#define num_letters_input 7
int main()
{
const int alphabet_count[26] = {8, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1};
const int alphabet_value[26] = {1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,1,1,1,1,4,4,8,4,10};
int letter_set[26];
int size_letter_set = 26;
void generate_letter_set(int letter_set[], int size_letter_set, int num_letters) {
int random_a = rand() % 26;
int random_b = rand() % (alphabet_count[random_a]);
letter_set[random_a] = random_b;
printf("Your letters are: ");
for(int i=0; i < size_letter_set; i++) {
if(letter_set[i])
{
int num = letter_set[i];
while(num--)
printf("%c ", i+97);
}
}
printf("\n");
}
int read_word(char word[], int max_size_word) {
printf("Enter your word: ");
scanf("%s", word);
printf("%s \n", word);
int size_word = strlen(word);
if(size_word > max_size_word)
read_word(word, max_size_word);
return size_word;
}
bool check_word(char word[], int size_word, int letter_set[], int size_letter_set) {
int count_array[26];
for(int i=0; i<size_word; i++) {
count_array[word[i]-97]++;
}
for(int i=0; i<size_letter_set; i++) {
if(count_array[i] <= letter_set[i])
continue;
else {
return false;
}
return true;
}
int compute_word_value(char word[], int size_word) {
int word_value = 0;
for(int i=0; i<size_word; i++) {
word_value = word_value + alphabet_value[word[i]-97];
}
return word_value;
}
int main(void) {
int max_size_word = 7;
int size_word, word_value;
bool validity = false;
char word[95];
printf("This program plays the game of scrabble.\n");
for(int i=0; i < size_letter_set; i++) {
letter_set[i] = 0;
}
generate_letter_set(letter_set, size_letter_set, num_letters_input);
while(!validity) {
size_word = read_word(word, max_size_word);
validity = check_word(word, size_word, letter_set, size_letter_set);
if(!validity)
{
printf("The word is not valid. Use your letters: ");
for(int i=0; i < size_letter_set; i++) {
if(letter_set[i])
{
int num = letter_set[i];
while(num--) {
printf("%c ", i+97);
}
}
printf("\n");
}
}
printf("The value of your word is: ");
word_value = compute_word_value(word, size_word);
printf("%d", word_value);
printf("Thank you for playing.");
}
}
}
return 0;
}
It may be somewhat different from what you intend,
I think it will be useful to start with the following modifications.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#define num_letters_input 7
const int alphabet_count[26] = {8,2,2,4,12,2,3,2,9,1,1,4,2,6,8,2, 1,6,4,6,4,2,2,1,2, 1};
const int alphabet_value[26] = {1,3,3,2, 1,4,2,4,1,8,5,1,3,1,1,3,10,1,1,1,1,4,4,8,4,10};
void generate_letter_set(int letter_set[], int size_letter_set, int num_letters) {
printf("Your letters are: ");
for(int i = 0; i < num_letters; i++){
int random_a = rand() % 26;
int random_b = rand() % alphabet_count[random_a];
letter_set[random_a] = random_b;
}
for(int i = 0; i < size_letter_set; ++i){
if(letter_set[i]){
int num = letter_set[i];
while(num--)
printf("%c ", 'a' + i);
}
}
printf("\n");
}
int read_word(char word[], int max_size_word) {
int size_word = 0;
do {
printf("Enter your word: ");
scanf("%s", word);
size_word = strlen(word);
} while(size_word > max_size_word);
return size_word;
}
bool check_word(char word[], int size_word, int letter_set[], int size_letter_set) {
int count_array[26] = {0};
for(int i = 0; i < size_word; i++) {
count_array[word[i]-'a']++;
}
for(int i=0; i < size_letter_set; i++) {
if(count_array[i] <= letter_set[i])
continue;
else
return false;
}
return true;
}
int compute_word_value(char word[], int size_word) {
int word_value = 0;
for(int i=0; i<size_word; i++) {
word_value += alphabet_value[word[i]-97];
}
return word_value;
}
int main(void){
int letter_set[26] = {0};
int size_letter_set = 26;
int max_size_word = num_letters_input;
int size_word, word_value;
bool validity = false;
char word[96];
srand(time(NULL));
printf("This program plays the game of scrabble.\n");
generate_letter_set(letter_set, size_letter_set, num_letters_input);
while(!validity) {
size_word = read_word(word, max_size_word);
validity = check_word(word, size_word, letter_set, size_letter_set);
if(!validity){
printf("The word is not valid.\nUse your letters: ");
}
}
printf("The value of your word is: ");
word_value = compute_word_value(word, size_word);
printf("%d\n", word_value);
printf("Thank you for playing.\n");
return 0;
}
I can't get my runner.c to see my mergesort.h import, just the last thing I need to do before I go through and add in comments.
Not seeing what I am doing wrong here so I thought I'd get more eyes to look at it. I looked up questions on here and also pretty much copied the template my lab professor has but it still won't work.
Error
/tmp/ccf8TT1E.o: In function `main':
/home/carson/CProgs/lab5/runner.c:10: undefined reference to `mergeSort'
/home/carson/CProgs/lab5/runner.c:11: undefined reference to `print'
collect2: error: ld returned 1 exit status
runner.c
#include <stdio.h>
#include <stdlib.h>
#include "mergesort.h"
int main()
{
int length = 4;
int array[4] = {7,5,3,1};
mergeSort(array, length);
print(array,length);
}
mergesort.h
#ifndef MERGESORT_H_
#define MERGESORT_H_
void mergeSort(int* x, int length);
#endif
mergesort.c
#include <stdio.h>
#include <stdlib.h>
#include "mergesort.h"
void mergeSort(int* array, int length)
{
if(length == 2)
{
if(array[1] < array[0])
{
swap(&array[1],&array[0]);
}
return;
}
else if(length == 1)
{
return;
}
else
{
if(length%2 == 0)
{
int halfLength = length/2;
int bottomHalf[halfLength];
int topHalf[halfLength];
int i;
for(i = 0; i <= (halfLength); i++)
{
bottomHalf[i] = array[i];
topHalf[i] = array[i+(halfLength)];
}
mergeSort(bottomHalf, halfLength);
mergeSort(topHalf, halfLength);
int arrayLoc = 0;
int bottomHalfLoc = 0;
int topHalfLoc = 0;
while(bottomHalfLoc < halfLength && topHalfLoc < halfLength)
{
if(bottomHalf[bottomHalfLoc] > topHalf[topHalfLoc])
{
array[arrayLoc] = topHalf[topHalfLoc];
topHalfLoc++;
}
else
{
array[arrayLoc] = bottomHalf[bottomHalfLoc];
bottomHalfLoc++;
}
arrayLoc++;
}
if(bottomHalfLoc < arrayLoc)
{
while(bottomHalfLoc < halfLength)
{
array[arrayLoc] = bottomHalf[bottomHalfLoc];
bottomHalfLoc++;
arrayLoc++;
}
}
return;
}else
{
int halfLength = length/2;
int bottomHalf[halfLength];
int topHalf[halfLength+1];
int i;
for(i = 0; i <= (halfLength); i++)
{
bottomHalf[i] = array[i];
}
for(i = 0; i <=(halfLength+1); i++)
{
topHalf[i] = array[i+halfLength];
}
mergeSort(bottomHalf, halfLength);
mergeSort(topHalf, halfLength);
int arrayLoc = 0;
int bottomHalfLoc = 0;
int topHalfLoc = 0;
while(bottomHalfLoc < halfLength && topHalfLoc < halfLength)
{
if(bottomHalf[bottomHalfLoc] > topHalf[topHalfLoc])
{
array[arrayLoc] = topHalf[topHalfLoc];
topHalfLoc++;
}
else
{
array[arrayLoc] = bottomHalf[bottomHalfLoc];
bottomHalfLoc++;
}
arrayLoc++;
}
if(bottomHalfLoc < arrayLoc)
{
while(bottomHalfLoc < halfLength)
{
array[arrayLoc] = bottomHalf[bottomHalfLoc];
bottomHalfLoc++;
arrayLoc++;
}
}
return;
}
}
}
void swap(int *smallerValue, int *largerValue)
{
int temp = *smallerValue;
*smallerValue = *largerValue;
*largerValue = temp;
}
void print(int array[], int length)
{
printf("%d",array[0]);
int i;
for(i = 1; i < length; i++)
{
printf(",%d",array[i]);
}
printf("\n");
}
use gcc *.c -o runner.out and one more thing i dont see print function in mergesort.h file but u r calling it in the main function. include it or use extern print(array,length);