I'm having a problem where my program - which runs fine in Windows - gives me a Segmentation Fault in Linux. I've searched through a lot of other questions that deal with Segmentation Faults and I think it has to do something with me not using malloc
correctly.
The program is supposed to take a data file, which is assumed to be a list events, which have multiple tasks and each task has an associated amount of days needed to complete it. For example, the data file I am testing with looks like this:
1 15 3
1 27 6
1 36 4
2 15 5
3 18 4
3 26 1
4 15 2
4 26 7
4 27 7
5 16 4
with the left column being the event number, the middle column being the task number, and the right column being the amount of days needed. Below is my code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
// Declare variables to be used
FILE *in;
FILE *out;
char* inName;
char* outName;
int eventNum, taskNum, daysNum;
int amtEvents, totalDays = 0;
int **events;
int **data, dataSize = 0;
int currentEvent = 1;
// Exit program if there are too few arguments entered
if(argc < 2)
{
printf("Too few arguments.");
return 0;
}
// Locate the -input and -output tags to determine
// file names
for(int i=0; i<argc; i++)
{
if(! strcmp(argv[i], "-input"))
{
inName = malloc(strlen(argv[i+1]) * (sizeof(char)));
strcpy(inName, argv[i+1]);
}
if(!strcmp(argv[i], "-output"))
{
outName = malloc(strlen(argv[i+1]) * (sizeof(char)));
strcpy(outName, argv[i+1]);
}
}
if ((in = fopen(inName, "r")) == NULL){
fprintf(stderr, "Input file usage: %s", inName);
return 0;
}
out = fopen(outName, "w");
while (!feof(in)) {
if (fscanf(in, "%d %d %d", &eventNum, &taskNum, &daysNum) != 3)
break;
dataSize++;
}
in = fopen(inName, "r");
// Store the data in the file into a
// dynamically created 2D array
data = malloc((dataSize) * sizeof(int));
while (!feof(in)) {
for(int i=0; i < dataSize+1; i++){
data[i] = malloc(3 * sizeof(int));
if (fscanf(in, "%d %d %d", &eventNum, &taskNum, &daysNum) != 3)
break;
data[i][0] = eventNum;
data[i][1] = taskNum;
data[i][2] = daysNum;
}
}
// Increment amtEvents for each unique event number
amtEvents = 1;
for(int i=0; i<dataSize; i++)
{
while(currentEvent != data[i][0])
{
amtEvents++;
currentEvent++;
}
}
// Create another 2D array to store data about
// each event
events = malloc(amtEvents * sizeof(int));
for(int i=0; i < amtEvents+1; i++)
{
events[i] = malloc(3 * sizeof(int));
for(int j=0; j<3; j++){
events[i][j] = 0;
}
}
for(int i=0; i < dataSize; i++)
{
events[data[i][0]-1][1]++;
if(data[i][2] > events[data[i][0]-1][2])
events[data[i][0]-1][2] = data[i][2];
}
// Header
fprintf(out, "Project completion timetable\n");
fprintf(out, "----------------------------------------\n");
fprintf(out, "Event\tNum of tasks\tMax num.of days\n");
fprintf(out, "-----\t------\t\t--------\n");
for(int i=0; i<amtEvents; i++)
{
fprintf(out, "%d\t %d\t\t %d\n", i+1, events[i][1], events[i][2]);
totalDays += events[i][2];
}
fprintf(out, "----------------------------------------\n");
fprintf(out, "Total number of days to finish the project: %d", totalDays);
free(inName);
free(outName);
free(data);
free(events);
}
I'm not very familiar with using gdb, but I ran my program through it and this is what it told me:
Program received signal SIGSEGV, Segmentation fault.
0x0000555555554ead in main ()
Ok, thanks for the help guys. I implemented some of the changes you guys suggested and it seems to be working fine now.
I think the cause of the error was me not remembering to account for the null terminator when using malloc
for inName
and outName
.