I'm doing a school assignment and I've only started on C programming a few months back. In this assignment, I'm to output the space occupied by a 'file'.
The initial output is correct, however, when i try to print out a table, the output becomes incorrect.
Codes:
#define TOTAL_DISK_BLOCKS 32
#define TOTAL_DISK_INODES 8
int blockStatus[TOTAL_DISK_BLOCKS]; // free = 0
int blockList[TOTAL_DISK_BLOCKS - TOTAL_DISK_INODES]; // list of blocks of a file
struct file_table
{
char fileName[20];
int fileSize;
struct block *sb; // start block
};
struct file_table fileTable[TOTAL_DISK_BLOCKS - TOTAL_DISK_INODES];
struct block
{
int blockNumber;
struct block *next;
} * head;
int AllocateBlocks(int Size)
{
int i = 0, count = 0, inList = 0, nextBlock = 0, j = 0, dcount = 0, fails = 0;
int allocStartBlock = TOTAL_DISK_INODES;
int allocEndBlock = TOTAL_DISK_BLOCKS - 1;
// check whether sufficient free blocks are available
// some codes here
{
for (j = 0; j < Size; j++)
{
nextBlock = (rand() % (allocEndBlock - allocStartBlock + 1)) + allocStartBlock;
if (blockStatus[nextBlock] == 0)
{
// printf("\ncount:%d\n", count);
blockList[j] = nextBlock;
count += 1;
}
else
{
count = 0;
fails += 1;
// printf("\nfails:%d, block %d taken\n", fails, nextBlock);
break;
}
}
}
// remaining blocks left
dcount = 0;
for (i = 0; i < (TOTAL_DISK_BLOCKS - TOTAL_DISK_INODES); i++)
if (blockStatus[i] == 0)
dcount++;
printf("Remaining blocks: %d\n", dcount);
if (count == Size)
{
for (j = 0; j < Size; j++)
{
blockStatus[blockList[j]] = 1;
}
return 0; // success
}
else
return 1; // not successful
}
void printBlockNumbers(struct block *temp)
{
// Return if list is empty
if (head == NULL)
{
printf("List is empty.");
return;
}
temp = head;
while (temp != NULL)
{
printf("-%d", temp->blockNumber); // Print data of current node
temp = temp->next; // Move to next node
}
}
void main()
{
int i = 0, j = 0, numFiles = 0, nextBlock = 0, ret = 1;
char s[20];
struct block *temp, *newBlock;
//some print codes here...
scanf("%d", &numFiles);
for (i = 0; i < numFiles; i++)
{
printf("\nEnter the name of file #%d: ", i + 1);
scanf("%s", fileTable[i].fileName);
printf("Enter the size (kB) of file #%d: ", i + 1);
scanf("%d", &fileTable[i].fileSize);
ret = AllocateBlocks(fileTable[i].fileSize);
if (ret == 0)
{
head = (struct block *)malloc(sizeof(struct block));
head->blockNumber = blockList[0];
head->next = NULL;
temp = head;
for (j = 1; j < fileTable[i].fileSize; j++)
{
newBlock = (struct block *)malloc(sizeof(struct block));
newBlock->blockNumber = blockList[j]; // Link data field of newNode
newBlock->next = NULL; // Make sure new node points to NULL
temp->next = newBlock; // Link previous node with newNode
temp = temp->next; // Make current node as previous node
}
printf("Blocks occupied");
printBlockNumbers(fileTable[i].sb);
printf("\nFile allocation success\n");
}
else
{
printf("\nFile allocation failed\n");
}
}
// Seed the pseudo-random number generator used by rand() with the value seed
srand(1234);
printf("\nFile Allocation Table\n");
printf("%s%20s%40s\n", "FILE_NAME", "FILE_SIZE", "BLOCKS_OCCUPIED");
for (i = 0; i < numFiles; i++)
{
printf("%s%20d", fileTable[i].fileName, fileTable[i].fileSize);
printf("\t\t\t\t");
printBlockNumbers(fileTable[i].sb);
printf("\n");
}
printf("File allocation completed. Exiting.\n");
}
Below is the first output.
Blocks occupied-15-30-17
Blocks occupied-21-10-27-10
Blocks occupied-20-26-12-24-19
And this is the table output.
File Allocation Table
FILE_NAME FILE_SIZE BLOCKS_OCCUPIED
3 3 -20-26-12-24-19
4 4 -20-26-12-24-19
5 5 -20-26-12-24-19
File allocation completed. Exiting.
In first loop you're printing newly allocated list each time, but in second loop you're printing last allocated list as you're printing from list which tail is a global variable head
.
in here:
void printBlockNumbers(struct block *temp)
{
// Return if list is empty
if (head == NULL)
{
printf("List is empty.");
return;
}
temp = head;
initial value of temp does not matter.
here:
head = (struct block *)malloc(sizeof(struct block));
head->blockNumber = blockList[0];
head->next = NULL;
temp = head;
you're assigning temp
value of head
, so temp->smth
points to the same address as head->smth
so when you use printBlockNumbers
to print head
it will print out what was assigned to it in this loop.
you should change printBlockNumbers
to that:
void printBlockNumbers(struct block *temp)
{
// Return if list is empty
if(!temp) {
return;
}
while (temp != NULL)
{
printf("-%d", temp->blockNumber); // Print data of current node
temp = temp->next; // Move to next node
}
and also assign fileTable[i].sb
value of head
in each loop and then free these lists at the end.
FYI: if you'd like to pass something to function as a "referece" (i.e. pointer) to be able to change original value in this function you do this like that:
void changeIntToFive(int* a) {
*a = 5;
}
int main(){
int var = 1;
changeIntToFive(&var);
printf("%d\n", var); // prints 5
}
and if you'd like to do the same to a pointer:
int glob = 5;
void makePtrPointToGlob(int** a) {
*a = &glob;
}
int main(){
int *ptr;
makePtrPointToGlob(&ptr);
printf("%d\n", *ptr); // prints 5
}