I want to save a struct containing a pointer that I use as a dynamic array but when I load the struct and malloc this pointer, it fails.
I have three structs (Orientation, ShipType, Status and PlayerType are enumerations, you can replace them by Int) :
struct Map
{
int width, height;
int* cases;
};
typedef struct Map Map;
struct Ship
{
int x, y, length, firstShoot, color;
int hasBeenDiscovered;
Orientation orientation;
ShipType type;
Status status;
};
typedef struct Ship Ship;
struct Player
{
int activeShips;
Map map[2];
char lastMoves[5][128];
Ship ships[10];
PlayerType type;
int shipcolor[4];
int color;
};
typedef struct Player Player;
I declare an array of 2 Player like this : Player players[2]; and initialize their properties. Then I want to save the struct in a file in order to load it afterwards.
Also, I use the Map struct as a 2d dynamic array using four functions :
void mallocMap(Map* map, int width, int height)
{
map->cases = malloc(sizeof(int) * width * height);
map->width = width;
map->height = height;
if (map->cases == NULL)
{
printf("Erreur d'allocation de memoire\n");
exit(0);
}
}
void freeMap(Map* map)
{
free(map->cases);
}
int getMapValue(Map map, int x, int y)
{
return *(map.cases + y*map.width + x);
}
void setMapValue(Map* map, int value, int x, int y)
{
*(map->cases + y*map->width + x) = value;
}
So when I store the struct, map.cases is only a pointer and I need to store the values at its address separately like so :
int save(Player players[2])
{
int* i;
FILE* file = NULL;
file = fopen("save.txt","w+");
if (file != NULL)
{
fwrite(players, sizeof(Player), 2, file);
fwrite(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fwrite(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fwrite(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fwrite(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
}
else
{
// error
}
fclose(file);
return 1;
}
Each player has 2 maps so there are 4 maps to store at the end.
The problem is in my load() function :
int load(Player players[2])
{
FILE* file = NULL;
file = fopen("save.txt","r");
if (file != NULL)
{
int *i;
fread(players, sizeof(Player), 2, file);
mallocMap(&players[0].map[0], players[0].map[0].width, players[0].map[0].height);
mallocMap(&players[0].map[1], players[0].map[1].width, players[0].map[1].height);
mallocMap(&players[1].map[0], players[1].map[0].width, players[1].map[0].height);
mallocMap(&players[1].map[1], players[1].map[1].width, players[1].map[1].height);
fread(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fread(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fread(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fread(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
}
else
{
// error
}
fclose(file);
return 1;
}
When I call mapAlloc(), it fails to allocate the memory and exit(0); my program stops.
The way you've declared your load function doesn't look right:
int load(Player* players[2])
This takes an array of pointers to Player, while your save routine takes an array of Player (i.e. Player players[2]). You probably need to change it to:
int load(Player players[2])
You're also reading the values back in to the wrong address:
for(i = players[0]->map[0].cases; i < players[0]->map[0].cases + players[0]->map[0].width * players[0]->map[0].height; i++)
fread(&i, sizeof(int), 1, file);
You're passing to fread the address of i. That means you're reading in an int and storing it in i, which is a local int * and not the dynamically allocated array you want to write to.
Remove the address-of operator here and pass in i directly, just like you do when you use fwrite
fread(i, sizeof(int), 1, file);
This will write the int that you read in into your array.
Also, there is no need to use loops to read / write individual ints here. Just do a single read / write passing in the number of values to read/write.
So saving would be:
fwrite(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fwrite(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fwrite(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fwrite(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
And loading would be:
fread(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fread(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fread(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fread(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
When compiling your code, there shouldn't be any warnings. If there are any, you're probably doing something wrong that you need to fix.
Related
The program only works for the first time. What was supposed to happen the second time was to add the same data to the binary file but that doesn't happen.
First run: It runs normal and it shows that it writed to the file.
Secound run: It writes to the file but doesnt read.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char *name, *role, *course;
int year, id;
} StudentFile;
void saveBin(StudentFile *studentsFile, int lines){
FILE *file = fopen("studentsx.bin","ab");
if (!file) {
printf("\n\n\tImposible to open file. \n\n");
exit(1);
}
for (int i = 0; i < lines; i++){
fwrite(&studentsFile[i], sizeof(StudentFile), 1, file);
}
fclose(file);
}
void readBin(){
StudentFile *studentsFile = malloc(sizeof(StudentFile)*5000);
FILE *file = fopen("studentsx.bin","rb");
if (!file) {
printf("\n\n\tImposible to open file. \n\n");
exit(1);
}
int j = 0;
while (fread(&studentsFile[j], sizeof(StudentFile), 1, file)){
printf("\nLine read %d: %s\t%s\t%d\t%d\t%s", j+1, studentsFile[j].name, studentsFile[j].role, studentsFile[j].year, studentsFile[j].id, studentsFile[j].course);
j++;
}
fclose(file);
}
void main(){
StudentFile *studentsFile = malloc(sizeof(StudentFile)*2);
int lines = 0;
studentsFile[0].name = "John";
studentsFile[0].role = "Gamer";
studentsFile[0].year = 1999;
studentsFile[0].id = 1;
studentsFile[0].course = "IOT";
studentsFile[1].name = "Piter";
studentsFile[1].role = "GamerXL";
studentsFile[1].year = 1991;
studentsFile[1].id = 2;
studentsFile[1].course = "IOTXL";
lines = 2;
saveBin(studentsFile, lines);
readBin();
}
You are writing pointers, not strings. fwrite writes single contiguous array of memory. In your case the StudentFiles and actual strings are scattered all over the static memory and heap memory.
Consider your struct:
typedef struct {
char *name, *role, *course;
int year, id;
} StudentFile;
it looks something like this in memory:
[<pointer to name><pointer to role><pointer to course><year><id>]
somewhere else in a different block of memory:
[John\0Gamer\0\OIT\o.......]
You wrote the first block above and left out the second one.
There are multiple approaches to this problem and we usually name them "serialization" - take your complex data structure and serialize it into a linear file.
One of the approaches is to allocate fixed size block within your structure StudentFile:
#define MAX_NAME 100
#define MAX_ROLE 100
#define MAX_COURSE 100
typedef struct {
char name[MAX_NAME];
char role[MAX_ROLE];
char course[MAX_COURSE];
int year, id;
} StudentFile;
then strings name, role and course will be inside of StudentFile:
[<100 bytes for name><100 bytes for role><100 bytes for course><year><id>]
this is contiguous block of memory and if can be written using single call to fwrite like you did.
But you won't be able to assign strings like you did with
studentsFile[i].name = "John";
C has strncpy for that:
strcpy(studentsFile[0].name, "John", MAX_NAME);
Another approach is to have several calls to fwrite. For every string, you write length first, then the string itself. For primitive types like int you just write that int.
First you gather strings from different locations pointed by the pointers:
size_t nameLen = strlen(studentsFile[i].name) + 1;/* +1 for the final zero*/
fwrite(&nameLen, sizeof(size_t), 1, file);
fwrite(studentsFile[i].name, nameLen, 1, file);
size_t roleLen = strlen(studentsFile[i].role) + 1;
fwrite(&roleLen, sizeof(size_t), 1, file);
fwrite(studentsFile[i].role, roleLen, 1, file);
size_t courseLen = strlen(studentsFile[i].course) + 1;
fwrite(&courseLen, sizeof(size_t), 1, file);
fwrite(studentsFile[i].course, courseLen, 1, file);
Then you write primitive types:
fwrite(&studentsFile[i].year, sizeof(int), 1, file);
fwrite(&studentsFile[i].id, sizeof(int), 1, file);
Next time when you read the file, you rely on the order of writes and read the fields back in the same order:
size_t nameLen;
fread(&nameLen, sizeof(size_t), 1, file);
char *name = malloc(nameLen);
fread(name, nameLen, 1, file);
size_t roleLen;
fread(&roleLen, sizeof(size_t), 1, file);
char *role = malloc(roleLen);
fread(role, roleLen, 1, file);
size_t courseLen;
fread(&courseLen, sizeof(size_t), 1, file);
char *course = malloc(courseLen);
fread(course, courseLen, 1, file);
int year;
fread(&year, sizeof(int), 1, file);
int id;
fread(&id, sizeof(int), 1, file);
printf("\nLine read %d: %s\t%s\t%d\t%d\t%s", j+1, name, role, year, id, course);
The problem lies somewhere else: Think carefully, what is your code doing with fwrite() here?
typedef struct {
char *name, *role, *course;
int year, id;
} StudentFile;
fwrite(&studentsFile[i], sizeof(StudentFile), 1, file);
What does the file content look like after writing a single element from studentFile?
Three strings and two integers (in their binary form)
Three pointers to somewhere and two integers (all in their binary forms)
I am exploring .tga files.
I have fully working code that looks like this:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
const int letterHeight = 34;
const int spacer = 5;
typedef struct{
uint8_t idlength;
uint8_t colourmaptype;
uint8_t datatypecode;
uint16_t colourmaporigin;
uint16_t colourmaplength;
uint8_t colourmapdepth;
uint16_t x_origin;
uint16_t y_origin;
uint16_t width;
uint16_t height;
uint8_t bitsperpixel;
uint8_t imagedescriptor;
} TGA_Header;
typedef struct
{
uint8_t B;
uint8_t G;
uint8_t R;
} Pixel;
typedef struct{
TGA_Header header;
Pixel* pixels;
int width;
int height;
} Image;
void readHeader(TGA_Header* header, FILE* input_F){
fread(&header->idlength, sizeof(header->idlength), 1, input_F);
fread(&header->colourmaptype, sizeof(header->colourmaptype), 1, input_F);
fread(&header->datatypecode, sizeof(header->datatypecode), 1, input_F);
fread(&header->colourmaporigin, sizeof(header->colourmaporigin), 1, input_F);
fread(&header->colourmaplength, sizeof(header->colourmaplength), 1, input_F);
fread(&header->colourmapdepth, sizeof(header->colourmapdepth), 1, input_F);
fread(&header->x_origin, sizeof(header->x_origin), 1, input_F);
fread(&header->y_origin, sizeof(header->y_origin), 1, input_F);
fread(&header->width, sizeof(header->width), 1, input_F);
fread(&header->height, sizeof(header->height), 1, input_F);
fread(&header->bitsperpixel, sizeof(header->bitsperpixel), 1, input_F);
fread(&header->imagedescriptor, sizeof(header->imagedescriptor), 1, input_F);
}
void writeHeader(TGA_Header* header, FILE* output_F){
fwrite(&header->idlength, sizeof(header->idlength), 1, output_F);
fwrite(&header->colourmaptype, sizeof(header->colourmaptype), 1, output_F);
fwrite(&header->datatypecode, sizeof(header->datatypecode), 1, output_F);
fwrite(&header->colourmaporigin, sizeof(header->colourmaporigin), 1, output_F);
fwrite(&header->colourmaplength, sizeof(header->colourmaplength), 1, output_F);
fwrite(&header->colourmapdepth, sizeof(header->colourmapdepth), 1, output_F);
fwrite(&header->x_origin, sizeof(header->x_origin), 1, output_F);
fwrite(&header->y_origin, sizeof(header->y_origin), 1, output_F);
fwrite(&header->width, sizeof(header->width), 1, output_F);
fwrite(&header->height, sizeof(header->height), 1, output_F);
fwrite(&header->bitsperpixel, sizeof(header->bitsperpixel), 1, output_F);
fwrite(&header->imagedescriptor, sizeof(header->imagedescriptor), 1, output_F);
}
void image_load(Image* image, const char* path){
FILE* input_F = fopen(path, "rb");
readHeader(&image->header, input_F);
image->width = image->header.width;
image->height = image->header.height;
image->pixels = (Pixel*) malloc(sizeof(Pixel) * image->header.width * image->header.height);
fread(image->pixels, sizeof(Pixel), image->header.width * image->header.height, input_F);
fclose(input_F);
}
void image_create(Image* image, const char* path){
FILE* output_F = fopen(path, "wb");
writeHeader(&image->header, output_F);
fwrite(image->pixels, sizeof(Pixel), image->header.width * image->header.height, output_F);
fclose(output_F);
}
void load_letters(Image (*letters)[26], const char* f){
char path[101];
for(int i=0; i<26; i++){
strcpy(path, f);
strcat(path, "/");
char c[2] = {(char)(65+i), '\0'};
strcat(path, c);
strcat(path, ".tga\0");
image_load(&(*letters)[i], &path[0]);
}
}
void drawLetter(Image* image, Image* letter, int X, int Y){
Y += letterHeight - letter->height;
int letter_y = letter->height;
int letter_x = letter->width;
int image_x = image->width;
for(int y=0; y<letter_y; y++){
for(int x=0; x<letter_x; x++){
if(letter->pixels[y*letter_x+x].R != (uint8_t)0 || letter->pixels[y*letter_x+x].G != (uint8_t)0 || letter->pixels[y*letter_x+x].B != (uint8_t)0){
image->pixels[(y+Y)*image_x+(x+X)] = letter->pixels[y*letter_x+x];
}
}
}
}
void drawString(Image* image, Image (*letters)[26], char (*text)[101], int Y){
int dejToSzajzym = 0;
for(int i=0; i<strlen((*text)); i++){
dejToSzajzym += (*letters)[(int)(*text)[i] - 65].width;
}
dejToSzajzym = dejToSzajzym/2;
dejToSzajzym = image->width/2 - dejToSzajzym;
for(int i=0; i<strlen(*text); i++){
if((*text)[i] != ' '){
drawLetter(image, &(*letters)[(int)(*text)[i] - 65], dejToSzajzym, Y);
dejToSzajzym += (*letters)[(int)(*text)[i] - 65].width;
}else{
dejToSzajzym += 10;
}
}
}
int main(int argc, char* argv[]){
Image* image;
Image letters[26];
image_load(image, "img1.tga");
load_letters(&letters, "font");
/*
char buffer[100];
*/
drawString(image, &letters, "LOL", 5);
image_create(image, "image.tga");
free(image->pixels);
image->pixels = NULL;
for(int i=0; i<26; i++){
free(letters[i].pixels);
letters[i].pixels = NULL;
}
return 0;
}
But when I write the declaration of buffer as shown (could be anywhere in main) the program immediately breaks.
It doesn´t even need to do anything.
error:
Unable to open 'memmove-vec-unaligned-erms.S': Unable to read file '/build/glibc-YYA7BZ/glibc-
2.31/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S'
(Error: Unable to resolve non-existing file '/build/glibc-YYA7BZ/glibc-2.31/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S').
BTW: Isn't there any easier way to copy the header data?
As noted by Retired Ninja in their comment, your primary problem is that Image *image; doesn't initialize image to point anywhere in particular. You pass the uninitialized pointer to image_load(), which then scribbles on memory — and you've no idea where. This is all undefined behaviour. Adding the variable buffer moves something around and changes the behaviour, but it is still undefined — anything goes and any (mis-)behaviour is valid, especially crashes. You must fix that! One way would be to change the definition to Image image; and pass &image to image_load() and the other functions that expect an Image *.
BTW: Isn't there any easier way to copy the header data?
Yes, there is, and there are a couple of ways to do it. The fundamental observation is that you could write the header with fwrite(header, sizeof(*header), 1, fp), and read it with fread(header, sizeof(*header), 1, fp).
However, with the data structure as currently defined, there is some padding in the structure — one byte after datatypecode and another after colourmapdepth. If you moved colourmapdepth after datatypecode (or anywhere near the start of the structure before the first uint16_t member), you'd save two bytes in memory and have no padding bytes on disk. OTOH, there's not a lot of harm in the padding bytes being read/written. It isn't clear to me whether you're dealing with an externally imposed header structure or whether you're free to modify it.
The best way to avoid padding in a structure is to put the most stringently aligned types at the start of the structure (uint16_t is more stringently aligned than uint8_t) and less stringently aligned types at the end. That normally avoids holes in the structure. There can still be padding at the end of the structure even so.
The compiler is attempting to call memmove and can't find it because you're running with no libraries.
Assuming you're doing what I think you're doing, the best way is to provide it. In another file, declare memmove like so.
void *memmove(void *sm, const void *tm, size_t n)
{
char *s = (char *)sm;
const char *t = (const char *)tm;
if (s > t) {
s += n;
t += n;
while (n--)
*--s = *--t;
} else {
while (n--)
*s++ = *t++;
}
return sm;
}
You may have to fiddle with the declaration to get the compiler to accept it.
Note that this is not the best possible memmove, it's the simplest. If it's too slow, write or obtain a faster one.
I'm trying to save a struct into a .dat file and read it back in later.
struct myStruct{
char **one;
mytype **two;
mytype2 *three;
}
With an assigning function:
struct MyStruct get_struct() = {
char **pi = ...;
mytype **pa = ...;
mytype2 **po = ...;
MyStruct n = {pi, pa, po};
return n;
}
I originally tried to save this struct into a .dat file by doing this:
struct MyStruct s = get_struct();
myoutfile = fopen("file.dat", "w");
if (myoutfile == NULL) {
fprintf(stderr, "\nError opend file\n");
exit(1);
}
fwrite(&s, sizeof(struct MyStruct), 1, myoutfile);
fclose(myoutfile);
and read it back in with:
fread(&t, sizeof(struct MyStruct), 1, myinfile)
Now I learned, that this does not work (segmentation error), because I only save the location where the pointer points to, not the actual thing.
Now my question is, how can I do it properly? I have found some solutions for C++ but I need to stay in C.
EDIT:
Later on, I want to call a function which looks like this:
void work_with_struct(MyStruct s){
char ** xone = s.one;
mytype **xtwo = s.two;
mytype2 *xthree = s.three;
}
This post is related to this post, but as I could specify my mistake now, asking in a new post makes more sense to me.
As always in programming, you break up the task to smaller chunks, and break up smaller chunks to yet smaller chunks, until every chunk is easy.
int saveMyStruct (struct myStruct* myStruct, FILE* file) {
// what do I do here?!?!
// well it has three members
// so treat each one in sequence
int result;
result = saveStringArray(myStruct->one, file);
if (result >= 0)
result = saveMyTypeArray (myStruct->two, file);
if (result >= 0)
result = saveMyType (myStruct->three, file);
return result;
}
Note how the status is checked all the time. If you work with files, you need to check the status all the time.
What next? You need to write three functions mentioned above.
saveStringArray(char** stringArray, FILE* file)
{
// first save the length of the array, then save each individual string
int length = getStringArrayLength(stringArray);
int result = fwrite(&length, sizeof(length), 1, file);
if (result != 1)
return -1;
for (i = 0; i < length; ++i)
{
result = saveString(stringArray[i], file);
if (result < 0)
return -1;
}
return i;
}
And so on and so forth. I presume your array of pointers is NULL-terminated; if not, you need to have some other way to know its length.
Note how array length is always saved before array elements. This is because you will need to read your array later, and you will need to know where to stop. It will also be easy to allocate your array when you read it.
So I need to write a function that reads all the elements inside a bit file. The point is that I don't know how many elements there could be inside, but I know what type of elements are. So I tried to write this function:
void loadData(Parallelogram **array) {
FILE *data; long size;
//int numberOfElements = 0;
int numberOfObjects = 0;
if ((data = fopen(name, "rb"))!=NULL) {
fseek(data, 0, SEEK_END);
size = ftell(data);
fseek(data, 0, SEEK_SET);
if (size<(long)sizeof(Parallelogram)) {
printf("The file is empty try to open another file maybe");
} else {
Parallelogram *tempArray;
numberOfObjects = size/sizeof(Parallelogram);
tempArray = realloc(*array, numberOfObjects*sizeof(Parallelogram));
if (tempArray==NULL) {
printf("There was an error reallocating memory");
} else { *array = tempArray; }
fread(*array, sizeof(Parallelogram), numberOfObjects, data);
}
}
fclose(data);
}
The elements are struct objects of type Parallelogram, storing a few floats.
The commented out part was me trying another method form another question but not understanding the real mechanism. Anyways when I call the function the array is empty. What am I getting wrong?
EDIT: As requested this is the main function where I call the function loadData()
int main() {
Parallelogram *paraArray = NULL;
loadData(¶Array);
}
EDIT: complete function more or less like the OP's.
You may do something like:
void loadData(Parallelogram **array, size_t * n) {
FILE *data;
if ((data = fopen("file.bin", "rb"))!=NULL) {
Parallelogram buffer[100]; // may be malloc'd
size_t chunk_size = 100;
size_t read_size = 0;
size_t number_of_objects = 0;
Parallelogram *aux = NULL;
*array = NULL;
while ((read_size = fread(buffer, sizeof *buffer, chunk_size, data)) > 0) {
aux = realloc(*array, (number_of_objects + read_size) * sizeof *buffer);
if (aux == NULL) {
// ERROR
free(*array);
// clean, break/exit
}
*array = aux;
memcpy(*array + number_of_objects, buffer, read_size*sizeof *buffer);
number_of_objects += read_size;
}
// check file for errors (ferror()) before exit
fclose(data);
*n = number_of_objects;
}
}
Consider the following abstracted code that reads some bytes from a file:
typedef struct A{
int size;
char * dataArray;
}A
A load(char* filename, int inSize)
{
A newA;
newA.size = inSize;
FILE *filePtr;
filePtr = fopen(filename,"rb");
char buff[1];
int i = 0;
newA.dataArray = ( char*)malloc(sizeof(char) * newA.size);
for (i = 0; i < newA.size; i++)
{
fread(buff, sizeof(char), 1, filePtr);
newA.dataArray[i] = buff[0];
}
char* copyOfDataArray = (char*)malloc(sizeof(char) * newA.size);
for (i = 0; i < newA.size; i++)
{
fread(buff, sizeof(char), 1, filePtr);
copyOfDataArray[i] = newA.dataArray[i];
}
newA.dataArray = copyOfDataArray;
return newA
}
void Initialize()
{
A first = load("file1", 100);
A second = load("file2", 20);
}
Both calls to function load return the expected result (data array has the same bytes as the file). Variables first and second are never used again.
However after a couple of hundreds lines of code the program always crashes with:
*malloc.c:2451: sYSMALLOC: Assertion '(old_top == (..... failed.*
The crash always occurs on the same line of code, but that line has nothing to do with variables first, second or even with struct A whatsoever.
My question is: is my way of instancing and loading 'first' and 'second' wrong? Can it cause some kind of memory leak / memory overflow that crashes the program long after the load function has finished?
Bonus: The crash does not occur if I only load "file1", as soon as i load both "file1" and "file2" the crash reappears.
Sorry for the long question.
You have memory leaks there. You have to free the previously allocated memory in newA.dataArray, before you assign there a new memory.
As stated by Joachim, read operation is very time consuming and you shall read data in blocks to minimize overhead.
Additionally, you have to close file descriptors, otherwise they will be depleted soon.
There are many issue on the code as already given by others.
Please checks bellow
typedef struct A{
int size;
char * dataArray;
}A
A load(char* filename, int inSize)
{
A newA;
newA.size = inSize;
FILE *filePtr = NULL ; //Use NULL
char buff[1]; //Size of buffer is only 1 ,If needed increase that to copy more at a time
int i = 0;
filePtr = fopen(filename,"rb");
//Try to check for the filePtr == NULL or not
newA.dataArray = ( char*)malloc(sizeof(char) * newA.size);
//Same checking should be done here
for (i = 0; i < size; i++) //What is size
{
fread(buff, sizeof(char), 1, filePtr);
newA.dataArray[i] = char[0]; //What is char[0]
}
//instead this you can read the bytes in a single call, use that.
// fread(buff, sizeof(char), <size to read >, filePtr);
char* copyOfDataArray = (char*)malloc(sizeof(char) * newA.size);
for (i = 0; i < size; i++)
{
fread(buff, sizeof(char), 1, filePtr);
copyOfDataArray[i] = newA.dataArray[i];
}
//why reading again once you done above.
newA.dataArray = copyOfDataArray;
return newA; //Please check: How you can return a auto variable.
}
void Initialize()
{
A first = load("file1", 100);
A second = load("file2", 20);
}