> Previously, I had made this array an array of longs rather than ints.
And did you change all your scanf "%d" to "%ld" when you did that?
Your code, with a very simple main() to call it.
And a single line to make sure the allocated memory has known 'junk'.
Code:
$ cat foo.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Each of the rooms is a row of the array
and each room attribute is a column of the array */
/* Room attributes:
* column 0 Room Number
* column 1 Location of room in room file (character offset)
* column 2 Number of the room to the north
* column 3 Number of the room to the east
* column 4 " " " " south
* column 5 " " " " west
* column 6 " " " " up
* column 7 " " " " down
*/
#define ROOM_ATTRIBUTES 8
/* The pointer to the room array needs to be passed to other functions,
* so this typedef is made in the header file
*/
typedef int (*rmArray)[ROOM_ATTRIBUTES];
rmArray Parse_Room_List(FILE *roomFile) {
int nextChar;
char nextLine[100];
int roomIndex = 0;
/* This is supposed to initialize the size of the room array.
* I expect my problem may be here.
*/
rmArray roomInfo = malloc(sizeof(int)*ROOM_ATTRIBUTES);
for(;;) {
nextChar = fgetc(roomFile);
/* If the next character is a "#" character, then the number that follows
* is a room number
*/
if (nextChar == '#') {
/* This resizes the array based on the number of rooms logged.
* I expect I may have a problem here too.
*/
roomInfo = realloc(roomInfo,(roomIndex+1)*sizeof(int)*ROOM_ATTRIBUTES);
/*!! fake the garbage */{ int i; for ( i = 0 ; i < ROOM_ATTRIBUTES ; i++) roomInfo[roomIndex][i] = -1; }
/* Gets the rest of the line, extracts the number, and stores it in
* the 0th attribute column for the current room index.
*/
fgets(nextLine,sizeof(nextLine),roomFile);
sscanf(nextLine,"%d",&roomInfo[roomIndex][0]);
/* Gets the current position in the file and stores it in the 1st
* attribute column.
*/
roomInfo[roomIndex][1]=(int) ftell(roomFile);
roomIndex++;
}
/* If the next character is a "@" character, then the number that follows
* is an attribue for the most recent room
*/
else if (nextChar == '@') {
roomIndex--;
/* nextChar stores the room attribute letter (n, e, s, w, u, or d)
* and nextLine stores the rest of the line following that character
*/
nextChar = fgetc(roomFile);
fgets(nextLine,sizeof(nextLine),roomFile);
/* Depending on which character was read, the number in the line
* is extracted and stored in the appropriate attribute column.
*/
switch(nextChar){
case 'n':
sscanf(nextLine,"%d",&roomInfo[roomIndex][2]);
break;
case 'e':
sscanf(nextLine,"%d",&roomInfo[roomIndex][3]);
break;
case 's':
sscanf(nextLine,"%d",&roomInfo[roomIndex][4]);
break;
case 'w':
sscanf(nextLine,"%d",&roomInfo[roomIndex][5]);
break;
case 'u':
sscanf(nextLine,"%d",&roomInfo[roomIndex][6]);
break;
case 'd':
sscanf(nextLine,"%d",&roomInfo[roomIndex][7]);
break;
}
roomIndex++;
}
else if (nextChar == EOF)
break;
}
return roomInfo;
}
int main ( ) {
FILE *fp = fopen("file.txt","r");
rmArray r = Parse_Room_List(fp);
fclose(fp);
for ( int i = 0 ; i < 5 ; i++ ) {
for ( int j = 0 ; j < ROOM_ATTRIBUTES ; j++ ) {
printf("%d ", r[i][j] );
}
printf("\n");
}
free(r);
return 0;
}
Your short data file
Code:
$ cat file.txt
#1
@n5
#2
@e5
#3
@s5
#4
@w5
#5
@n3
@e4
@s1
@w2
Compile and run.
Note that all the output is as expected. Everything that isn't in the file is -1.
There are no bad memory accesses, and no leaks.
Code:
$ gcc -std=c99 -W -Wall foo.c
$ valgrind ./a.out
==3433== Memcheck, a memory error detector.
==3433== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==3433== Using LibVEX rev 1884, a library for dynamic binary translation.
==3433== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==3433== Using valgrind-3.4.1-Debian, a dynamic binary instrumentation framework.
==3433== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==3433== For more details, rerun with: -v
==3433==
1 3 5 -1 -1 -1 -1 -1
2 10 -1 5 -1 -1 -1 -1
3 17 -1 -1 5 -1 -1 -1
4 24 -1 -1 -1 5 -1 -1
5 31 3 4 1 2 -1 -1
==3433==
==3433== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1)
==3433== malloc/free: in use at exit: 0 bytes in 0 blocks.
==3433== malloc/free: 7 allocs, 7 frees, 864 bytes allocated.
==3433== For counts of detected errors, rerun with: -v
==3433== All heap blocks were freed -- no leaks are possible.
$