I am trying to solve a problem in an assignment I was given - the problem being is that one of the functions I am currently implementing does not work.
First and foremost, I was told that code provided by my professor (down below) cannot be modified in any way:
#include <crtdbg.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#define BLOCK_SIZE 64
typedef enum { FALSE = 0, TRUE } BOOL;
typedef struct {
char* fileName; // Frame fileName
}Frame, *pFrame, **ppFrame;
typedef struct {
unsigned int numFrames; // number of Frame*
ppFrame frames; // array of Frame*
}Animation, *pAnimation;
// Forward declarations
void initAnimation(pAnimation);
void insertFrame(pAnimation);
void deleteFrames(pAnimation);
void runFrames(pAnimation);
int main(void)
{
char response;
BOOL RUNNING = TRUE;
Animation A;
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
initAnimation(&A);
while (RUNNING)
{
printf("MENU\n 1. Insert a Frame\n 2. Delete all the Frames\n 3. Run the Animation\n 4. Quit\n");
scanf("%c", &response);
switch (response)
{
case '1':insertFrame(&A); break;
case '2':deleteFrames(&A); break;
case '3':runFrames(&A); break;
case '4':RUNNING = FALSE; deleteFrames(&A); break;
default:printf("Please enter a valid option\n");
}
printf("\n");
while ((response = getchar()) != '\n' && response != EOF);// clear input buffer
}
return 0;
}
Next, I needed to create functions for the forward declaration statements in the provided code. The function that I am having problems with is here:
void insertFrame(Animation *pAnimation)
{
char input[50];
int count;
int dupe = 0;
int blockFrames = pAnimation->numFrames % BLOCK_SIZE;
int blocks = (pAnimation->numFrames / BLOCK_SIZE) + 1;
printf("Insert a frame into the Animation\n");
scanf("%s", input);
/* check the input to see if it matches any of the existing frames */
for (count = 0; count < pAnimation->numFrames; count++)
{
printf("%s\n", pAnimation->frames[count]->fileName); /*test: show the file name to be compared against*/
if (strcmp(input, pAnimation->frames[count]->fileName) != 0)
{
dupe = 1;
printf("Dupe detected!");
return;
}
}
printf("dupe = %d\n", dupe);
/* afterwards, actually add the frame if it's ok */
if (dupe == 0)
{
pAnimation->numFrames++;
strcpy(pAnimation->frames[pAnimation->numFrames - 1]->fileName, input); /* <-- This is where the error happens */
}
}
Every time I use printf or strcpy to show or modify the fileName struct member from pAnimation->frames[ ], it shows a read access violation. Upon closer inspection, it appears that the fileName from the address pointed from pAnimation->frames[ ] is unknown.
Why is this happening, and how do I fix it?
Okay, so after taking the advice, this is what my initAnimation looks like:
void initAnimation(Animation *pAnimation)
{
pAnimation->numFrames = 0;
pAnimation->frames = malloc(BLOCK_SIZE * sizeof(Frame));
}
I have also got in contact with my professor, and he said that I didn't need to allocate anything unless I am "adding" a new frame (via insertFrame). I'm not entirely sure what he meant by that.
Looking at
void initAnimation(Animation *pAnimation)
{
pAnimation->numFrames = 0;
pAnimation->frames = malloc(BLOCK_SIZE * sizeof(Frame));
}
I assume you are allocating an array of frame pointers. So each cell is sizeof(pFrame)
not sizeof(Frame)
. That is big enough to hold a pointer to a frame not a frame itself.
Second you need to allocate these frames as you create them.
Something like
pAnimation->frames[i] = malloc(sizeof(Frame));
Finally a Frame
holds a Pointer to character array. You need to allocate that as well
pAnimation->frames[i]->fileName = malloc(50); // Use your max size
Also you should be checking the results of the malloc
calls.
I would put the 2 frame allocation calls in insertFrame()
as that is when you are creating/adding a new frame.