Hello:
I've been working on an assignment and I have hit a stumbling block pertaining to an array of pointers.
If I am correct in my assumptions, the array
should have its address passed to a function when calling it like this:
Once I am in somefunc, if I call the line of code:
causes the program to crash. Specifically the error is commented out on line 261 of hw2************ ***Driver.c below. Thank you to anyone who can enlighten me on why this seemingly innoculous line is causing the program to crash.
-fauxanadu
hw2************ ***Constants.c
[CODE=c]
/*************** *************** *************** *************** *************** ***
* PROGRAMMER : *************** *
* LANGUAGE : C *
* CLASS : CSE 1320-002, Fall 2007 *
* COMPILER : gcc *
* OPERATING SYSTEM : Unix *
* PLATFORM : omega *
* COURSE : Intermmediate Programming *
* ASSIGNMENT : Homework 1 *
* ASSIGNED : 27 September 2007 *
* DUE : 16 October 2007 *
* FILED AS : hw2************ ***Constants.c *
* FILES USED : hw2************ ***Constants.c *
* : hw2************ ***Driver.c *
* CONCEPTS : Structures, dynamic memory (de)allocation, file I/O *
* : Command Line Arguments *
* WEIGHT : 10% of Final Grade *
* PURPOSE : Include required system files *
* Define global constants *
* Prototype Functions *
*************** *************** *************** *************** *************** **/
// System Files
#include <stdlib.h>
#include <stdio.h>
// Constants
#define CMD_ARGS 2
#define CMD_CHAR '*'
#define CMD_INDEX 0
#define CTRL_INDEX 1
#define CTRL_END 'E'
#define CTRL_FEED 'f'
#define CTRL_PRCH 'p'
#define CTRL_TRAN 't'
#define DISP_FLOAT 4
#define DISP_INT 4
#define DISP_NAME 11
#define DISP_PREC 1
#define DISP_STRING 7
#define ERR_NONE 0
#define ERR_BAD_ARGS 1
#define ERR_MISSING_FIL E 2
#define ERR_MALFORMED 3
#define FALSE 0
#define FILE_INDEX 1
#define LINE_SIZE 51
#define LOW_INDEX 0
#define NULLS '\0'
#define NULLP 0
#define STRING_LARGE 20
#define STRING_SMALL 10
#define STARTI 0
#define STARTT 0
#define TRUE 1
#define ZEROF 0.0
#define ZEROI 0
#define ZOO_SIZE 4
// Objects
struct Animal
{
char color[STRING_LARGE];
char name[STRING_LARGE];
char species[STRING_LARGE];
double food;
double water;
int age;
int id;
int weight;
};
// Function Prototypes
void purchase(FILE** , struct Animal*[], char[]);
void maintain(FILE** , struct Animal*[], char[]);
void report(struct Animal*[]);
void transfer(FILE** , struct Animal*[], char[]);
[/CODE]
hw2************ ***Driver.c
[CODE=c]/*************** *************** *************** *************** *************** **
* PROGRAMMER : *************** * *
* LANGUAGE : C *
* CLASS : CSE 1320-002, Fall 2007 *
* COMPILER : gcc *
* OPERATING SYSTEM : Unix *
* PLATFORM : omega *
* COURSE : Intermmediate Programming *
* ASSIGNMENT : Homework 1 *
* ASSIGNED : 27 September 2007 *
* DUE : 16 October 2007 *
* FILED AS : hw2************ ***Driver.c *
* FILES USED : hw2************ ***Constants.c *
* : hw2************ ***Driver.c *
* CONCEPTS : Structures, dynamic memory (de)allocation, file I/O *
* : Command Line Arguments *
* WEIGHT : 10% of Final Grade *
* PURPOSE : Define Functions *
*************** *************** *************** *************** *************** **/
#include "hw2*********** *****Constants. c"
int main(int argc, char* argv[])
{
//Variable Declaration
char lineIn[LINE_SIZE] = {NULLS};
FILE* input = {ZEROI};
struct Animal* zoo[ZOO_SIZE] = {NULLP};
// Checks that there were 2 arguments passed at the command line
if(argc != CMD_ARGS)
{
printf("\nError %d", ERR_BAD_ARGS);
printf("\nThe proper syntax is:");
printf("\n>exec utable.exe file.dat\n");
exit(ERR_BAD_AR GS);
}
// Opens the file and checks for success
input = fopen(argv[FILE_INDEX], "r");
if (!input)
{
printf("\nError %d", ERR_MISSING_FIL E);
printf("\nThe file %s could not be opened. \n", argv[FILE_INDEX]);
exit(ERR_MISSIN G_FILE);
}
// Gets a line of input and determines which function to call
fgets(lineIn, LINE_SIZE - 1, input);
while(!(lineIn[CMD_INDEX] == CMD_CHAR & lineIn[CTRL_INDEX] == CTRL_END))
{
printf("\n");
if(lineIn[CMD_INDEX] == CMD_CHAR)
{
switch(lineIn[CTRL_INDEX])
{
case CTRL_FEED:
maintain(&input , zoo, lineIn);
break;
case CTRL_PRCH:
purchase(&input , zoo, lineIn);
break;
case CTRL_TRAN:
transfer(&input , zoo, lineIn);
break;
default:
printf("\nError %d", ERR_MALFORMED);
printf("\nThe input file is malformed.");
printf("\nPleas e consult the documentation\n ");
exit(ERR_MALFOR MED);
}
}
report(zoo);
}
return ERR_NONE;
}
void purchase(FILE** input, struct Animal* zoo[], char lineIn[])
{
//Variable Declaration
int i = ZEROI;
char a[STRING_SMALL], b[STRING_SMALL], c[STRING_SMALL],
d[STRING_SMALL], e[STRING_SMALL], f[STRING_SMALL],
g[STRING_SMALL];
//Gets line of input
fgets(lineIn, LINE_SIZE - 1, *input);
//Exit Condition
if(lineIn[CMD_INDEX] == CMD_CHAR)
{
return;
}
for(i = STARTI; i < ZOO_SIZE; i++)
{
if (zoo[i] == NULLP)
{
zoo[i] = (struct Animal*)malloc( 1 * sizeof(struct Animal));
sscanf(lineIn, "%s%s%s%s%s%s%s ", a, b, c, d, e, f, g);
strcpy(zoo[i]->species, a);
strcpy(zoo[i]->name, b);
if(!(isdigit(c[LOW_INDEX])))
{
strcat(zoo[i]->name, " ");
strcat(zoo[i]->name, c);
zoo[i]->age = atoi(d);
zoo[i]->weight = atoi(e);
zoo[i]->id = atoi(f);
strcpy(zoo[i]->color, g);
}
else
{
zoo[i]->age = atoi(c);
zoo[i]->weight = atoi(d);
zoo[i]->id = atoi(e);
strcpy(zoo[i]->color, f);
}
zoo[i]->food = ZEROF;
zoo[i]->water = ZEROF;
printf("Purchas ing: %s\n", zoo[i]->name);
break;
}
}
//Makes sure the for loop exited early, if not, inform user
if(i >= ZOO_SIZE)
{
sscanf(lineIn, "%s%s%s%s%s%s%s ", a, b, c, d, e, f, g);
printf("Purchas e failed: %s ", b);
if(!(isdigit(c[LOW_INDEX])))
{
printf("%s ", c);
}
printf("\n");
}
//Recurses and then returns
purchase(input, zoo, lineIn);
return;
}
void maintain(FILE** input, struct Animal* zoo[], char lineIn[])
{
//Variable Declaration
int i = ZEROI;
char a[STRING_LARGE], b[STRING_SMALL], c[STRING_SMALL], d[STRING_SMALL];
//Gets line of input
fgets(lineIn, LINE_SIZE - 1, *input);
//Exit Condition
if(lineIn[CMD_INDEX] == CMD_CHAR)
{
return;
}
//Separates out the desired data
sscanf(lineIn, "%s%s%s%s", a, b, c, d);
if(!(isdigit(b[LOW_INDEX])))
{
strcat(a, " ");
strcat(a, b);
}
for(i = STARTI; i < ZOO_SIZE; i++)
{
if(!(strcmp(zoo[i]->name, a)))
{
printf("Maintai ning: %s\n", zoo[i]->name);
if(isdigit(b[LOW_INDEX]))
{
zoo[i]->food = atof(b);
zoo[i]->water = atof(c);
}
else
{
zoo[i]->food = atof(c);
zoo[i]->water = atof(d);
}
}
}
//Recurses and then returns
maintain(input, zoo, lineIn);
return;
}
void report(struct Animal* zoo[])
{
//Variable Declaration
static int headerPrinted = FALSE;
static int i = ZEROI;
//Exit condition
if(i >= ZOO_SIZE)
{
return;
}
//If the header has not been printed, prints it
if(headerPrinte d == FALSE)
{
printf("----+------------+--------+-----+-------+--------+------+------\n");
printf("ID |Name |Species |Age |Weight |Color |Food |Water \n");
printf("----+------------+--------+-----+-------+--------+------+------\n");
headerPrinted = TRUE;
}
if(zoo[i])
{ //Prints out the current animals information
printf("%-*d|%-*s |%-*s |%*d | %*d |%-*s | %*.*f | %*.*f \n",
DISP_INT, zoo[i]->id,
DISP_NAME, zoo[i]->name,
DISP_STRING, zoo[i]->species,
DISP_INT, zoo[i]->age,
DISP_INT, zoo[i]->weight,
DISP_STRING, zoo[i]->color,
DISP_FLOAT, DISP_PREC, zoo[i]->food,
DISP_FLOAT, DISP_PREC, zoo[i]->water);
}
//Recurses and resets variables for next print
i++;
report(zoo);
headerPrinted = FALSE;
i = ZEROI;
return;
}
void transfer(FILE** input, struct Animal* zoo[], char lineIn[])
{
//Variable Declaration
int i = ZEROI;
char a[STRING_SMALL];
//Gets line of input
fgets(lineIn, LINE_SIZE - 1, *input);
//Exit Condition
if(lineIn[CMD_INDEX] == CMD_CHAR)
{
return;
}
//Separates out the desired information
sscanf(lineIn, "%s%s%s%s%s%s%s ", a);
//Checks each element of the zoo to see if it matches
for(i = ZEROI; i < ZOO_SIZE; i++)
{
if(!(strcmp(zoo[i]->name, a)))
{
printf("Transfe ring: %s\n", zoo[i]->name);
free((struct Animal*)zoo[i]);
//zoo[i] = (struct Animal*)NULLP;
break;
}
}
if(i >= ZOO_SIZE)
{
printf("Transfe r Failed: %s", lineIn);
}
//Recurses and then returns
transfer(input, zoo, lineIn);
return;
}[/CODE]
I've been working on an assignment and I have hit a stumbling block pertaining to an array of pointers.
If I am correct in my assumptions, the array
Code:
struct animal* zoo[4]
Code:
somefunc(zoo);
Code:
free(zoo[0]); zoo[0] = 0;
-fauxanadu
hw2************ ***Constants.c
[CODE=c]
/*************** *************** *************** *************** *************** ***
* PROGRAMMER : *************** *
* LANGUAGE : C *
* CLASS : CSE 1320-002, Fall 2007 *
* COMPILER : gcc *
* OPERATING SYSTEM : Unix *
* PLATFORM : omega *
* COURSE : Intermmediate Programming *
* ASSIGNMENT : Homework 1 *
* ASSIGNED : 27 September 2007 *
* DUE : 16 October 2007 *
* FILED AS : hw2************ ***Constants.c *
* FILES USED : hw2************ ***Constants.c *
* : hw2************ ***Driver.c *
* CONCEPTS : Structures, dynamic memory (de)allocation, file I/O *
* : Command Line Arguments *
* WEIGHT : 10% of Final Grade *
* PURPOSE : Include required system files *
* Define global constants *
* Prototype Functions *
*************** *************** *************** *************** *************** **/
// System Files
#include <stdlib.h>
#include <stdio.h>
// Constants
#define CMD_ARGS 2
#define CMD_CHAR '*'
#define CMD_INDEX 0
#define CTRL_INDEX 1
#define CTRL_END 'E'
#define CTRL_FEED 'f'
#define CTRL_PRCH 'p'
#define CTRL_TRAN 't'
#define DISP_FLOAT 4
#define DISP_INT 4
#define DISP_NAME 11
#define DISP_PREC 1
#define DISP_STRING 7
#define ERR_NONE 0
#define ERR_BAD_ARGS 1
#define ERR_MISSING_FIL E 2
#define ERR_MALFORMED 3
#define FALSE 0
#define FILE_INDEX 1
#define LINE_SIZE 51
#define LOW_INDEX 0
#define NULLS '\0'
#define NULLP 0
#define STRING_LARGE 20
#define STRING_SMALL 10
#define STARTI 0
#define STARTT 0
#define TRUE 1
#define ZEROF 0.0
#define ZEROI 0
#define ZOO_SIZE 4
// Objects
struct Animal
{
char color[STRING_LARGE];
char name[STRING_LARGE];
char species[STRING_LARGE];
double food;
double water;
int age;
int id;
int weight;
};
// Function Prototypes
void purchase(FILE** , struct Animal*[], char[]);
void maintain(FILE** , struct Animal*[], char[]);
void report(struct Animal*[]);
void transfer(FILE** , struct Animal*[], char[]);
[/CODE]
hw2************ ***Driver.c
[CODE=c]/*************** *************** *************** *************** *************** **
* PROGRAMMER : *************** * *
* LANGUAGE : C *
* CLASS : CSE 1320-002, Fall 2007 *
* COMPILER : gcc *
* OPERATING SYSTEM : Unix *
* PLATFORM : omega *
* COURSE : Intermmediate Programming *
* ASSIGNMENT : Homework 1 *
* ASSIGNED : 27 September 2007 *
* DUE : 16 October 2007 *
* FILED AS : hw2************ ***Driver.c *
* FILES USED : hw2************ ***Constants.c *
* : hw2************ ***Driver.c *
* CONCEPTS : Structures, dynamic memory (de)allocation, file I/O *
* : Command Line Arguments *
* WEIGHT : 10% of Final Grade *
* PURPOSE : Define Functions *
*************** *************** *************** *************** *************** **/
#include "hw2*********** *****Constants. c"
int main(int argc, char* argv[])
{
//Variable Declaration
char lineIn[LINE_SIZE] = {NULLS};
FILE* input = {ZEROI};
struct Animal* zoo[ZOO_SIZE] = {NULLP};
// Checks that there were 2 arguments passed at the command line
if(argc != CMD_ARGS)
{
printf("\nError %d", ERR_BAD_ARGS);
printf("\nThe proper syntax is:");
printf("\n>exec utable.exe file.dat\n");
exit(ERR_BAD_AR GS);
}
// Opens the file and checks for success
input = fopen(argv[FILE_INDEX], "r");
if (!input)
{
printf("\nError %d", ERR_MISSING_FIL E);
printf("\nThe file %s could not be opened. \n", argv[FILE_INDEX]);
exit(ERR_MISSIN G_FILE);
}
// Gets a line of input and determines which function to call
fgets(lineIn, LINE_SIZE - 1, input);
while(!(lineIn[CMD_INDEX] == CMD_CHAR & lineIn[CTRL_INDEX] == CTRL_END))
{
printf("\n");
if(lineIn[CMD_INDEX] == CMD_CHAR)
{
switch(lineIn[CTRL_INDEX])
{
case CTRL_FEED:
maintain(&input , zoo, lineIn);
break;
case CTRL_PRCH:
purchase(&input , zoo, lineIn);
break;
case CTRL_TRAN:
transfer(&input , zoo, lineIn);
break;
default:
printf("\nError %d", ERR_MALFORMED);
printf("\nThe input file is malformed.");
printf("\nPleas e consult the documentation\n ");
exit(ERR_MALFOR MED);
}
}
report(zoo);
}
return ERR_NONE;
}
void purchase(FILE** input, struct Animal* zoo[], char lineIn[])
{
//Variable Declaration
int i = ZEROI;
char a[STRING_SMALL], b[STRING_SMALL], c[STRING_SMALL],
d[STRING_SMALL], e[STRING_SMALL], f[STRING_SMALL],
g[STRING_SMALL];
//Gets line of input
fgets(lineIn, LINE_SIZE - 1, *input);
//Exit Condition
if(lineIn[CMD_INDEX] == CMD_CHAR)
{
return;
}
for(i = STARTI; i < ZOO_SIZE; i++)
{
if (zoo[i] == NULLP)
{
zoo[i] = (struct Animal*)malloc( 1 * sizeof(struct Animal));
sscanf(lineIn, "%s%s%s%s%s%s%s ", a, b, c, d, e, f, g);
strcpy(zoo[i]->species, a);
strcpy(zoo[i]->name, b);
if(!(isdigit(c[LOW_INDEX])))
{
strcat(zoo[i]->name, " ");
strcat(zoo[i]->name, c);
zoo[i]->age = atoi(d);
zoo[i]->weight = atoi(e);
zoo[i]->id = atoi(f);
strcpy(zoo[i]->color, g);
}
else
{
zoo[i]->age = atoi(c);
zoo[i]->weight = atoi(d);
zoo[i]->id = atoi(e);
strcpy(zoo[i]->color, f);
}
zoo[i]->food = ZEROF;
zoo[i]->water = ZEROF;
printf("Purchas ing: %s\n", zoo[i]->name);
break;
}
}
//Makes sure the for loop exited early, if not, inform user
if(i >= ZOO_SIZE)
{
sscanf(lineIn, "%s%s%s%s%s%s%s ", a, b, c, d, e, f, g);
printf("Purchas e failed: %s ", b);
if(!(isdigit(c[LOW_INDEX])))
{
printf("%s ", c);
}
printf("\n");
}
//Recurses and then returns
purchase(input, zoo, lineIn);
return;
}
void maintain(FILE** input, struct Animal* zoo[], char lineIn[])
{
//Variable Declaration
int i = ZEROI;
char a[STRING_LARGE], b[STRING_SMALL], c[STRING_SMALL], d[STRING_SMALL];
//Gets line of input
fgets(lineIn, LINE_SIZE - 1, *input);
//Exit Condition
if(lineIn[CMD_INDEX] == CMD_CHAR)
{
return;
}
//Separates out the desired data
sscanf(lineIn, "%s%s%s%s", a, b, c, d);
if(!(isdigit(b[LOW_INDEX])))
{
strcat(a, " ");
strcat(a, b);
}
for(i = STARTI; i < ZOO_SIZE; i++)
{
if(!(strcmp(zoo[i]->name, a)))
{
printf("Maintai ning: %s\n", zoo[i]->name);
if(isdigit(b[LOW_INDEX]))
{
zoo[i]->food = atof(b);
zoo[i]->water = atof(c);
}
else
{
zoo[i]->food = atof(c);
zoo[i]->water = atof(d);
}
}
}
//Recurses and then returns
maintain(input, zoo, lineIn);
return;
}
void report(struct Animal* zoo[])
{
//Variable Declaration
static int headerPrinted = FALSE;
static int i = ZEROI;
//Exit condition
if(i >= ZOO_SIZE)
{
return;
}
//If the header has not been printed, prints it
if(headerPrinte d == FALSE)
{
printf("----+------------+--------+-----+-------+--------+------+------\n");
printf("ID |Name |Species |Age |Weight |Color |Food |Water \n");
printf("----+------------+--------+-----+-------+--------+------+------\n");
headerPrinted = TRUE;
}
if(zoo[i])
{ //Prints out the current animals information
printf("%-*d|%-*s |%-*s |%*d | %*d |%-*s | %*.*f | %*.*f \n",
DISP_INT, zoo[i]->id,
DISP_NAME, zoo[i]->name,
DISP_STRING, zoo[i]->species,
DISP_INT, zoo[i]->age,
DISP_INT, zoo[i]->weight,
DISP_STRING, zoo[i]->color,
DISP_FLOAT, DISP_PREC, zoo[i]->food,
DISP_FLOAT, DISP_PREC, zoo[i]->water);
}
//Recurses and resets variables for next print
i++;
report(zoo);
headerPrinted = FALSE;
i = ZEROI;
return;
}
void transfer(FILE** input, struct Animal* zoo[], char lineIn[])
{
//Variable Declaration
int i = ZEROI;
char a[STRING_SMALL];
//Gets line of input
fgets(lineIn, LINE_SIZE - 1, *input);
//Exit Condition
if(lineIn[CMD_INDEX] == CMD_CHAR)
{
return;
}
//Separates out the desired information
sscanf(lineIn, "%s%s%s%s%s%s%s ", a);
//Checks each element of the zoo to see if it matches
for(i = ZEROI; i < ZOO_SIZE; i++)
{
if(!(strcmp(zoo[i]->name, a)))
{
printf("Transfe ring: %s\n", zoo[i]->name);
free((struct Animal*)zoo[i]);
//zoo[i] = (struct Animal*)NULLP;
break;
}
}
if(i >= ZOO_SIZE)
{
printf("Transfe r Failed: %s", lineIn);
}
//Recurses and then returns
transfer(input, zoo, lineIn);
return;
}[/CODE]
Comment