Cik02
Cik02

Reputation: 59

using malloc - c programming

I'm wondering if anyone can help me with my below code. I'm struggling to implement dynamic allocation for my program when reading data from a file and storing it in a struct. I'm new to both structs and dynamic allocation. While my program seems to be storing the data successfully into the struct I can see in Visual Studio that the allocation of these is not correct. Any advice on storing the data dynamic would be much appreciated. I was trying to use malloc but could not get this to work for me.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void load_data();


typedef struct {
    char name[12];
    char vaccinevendor[8];
    char vaccinationdate[12];
    char dob[12];
    char underlyingcond[8];
    char id[7];
}  Record;



int main(void)
{

    load_data();

    return 0;
}

void load_data()
{
    
    Record s1[2];


    FILE* Ptr;  /*file pointer*/

    if ((Ptr = fopen("records.txt", "rb")) == NULL) {
        printf("File does not exist\n");
    
        Ptr = fopen("records.txt", "w");
        if (Ptr != NULL)
            printf("records.txt file has now been created.\n");
        else {
            printf("Unable to create file!\n");
            return 1;
        }
    }


     Ptr = (char*)malloc(1000 * sizeof(char));

    // read file contents till end of file
    fread(&s1, sizeof(Record), 2, Ptr);
    
    fclose(Ptr); /*close stream*/

}

Hi all,

As per my comment below I have updated my code but am getting errors when trying to store my array strings into my struct. As I was asked in the comments also, the test file contents are lines in the following format:

John Smith
Pfizer
02/08/2021
06/01/1990
None
556679

Mary Jones
None
None
09/10/1988
Asthma
556677
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 13
#define stringlen 15
#define numoflines 12

void load_data();


typedef struct {
    char name[12];
    char vaccinevendor[8];
    char vaccinationdate[12];
    char dob[12];
    char underlyingcond[8];
    char id[7];
}  Record;



int main(void)
{

    load_data();

    return 0;
}

void load_data()
{
    char line[110], buff[13][50];
    int len;
    int i = 0;

    Record s1[2];


    FILE* Ptr;  /*file pointer*/

    if ((Ptr = fopen("records.txt", "rb")) == NULL) {
        printf("File does not exist\n");
    
        Ptr = fopen("records.txt", "w");
        if (Ptr != NULL)
            printf("records.txt file has now been created.\n");
        else {
            printf("Unable to create file!\n");
            return 1;
        }
    }

    for (i = 0; i < SIZE; ++i)
    {
        len = strlen(buff[i]);
        fgets(buff[i], 21, Ptr);
        s1[0] = malloc(len);
        strcpy(s1[i], buff);
    }

    fclose(Ptr); /*close stream*/

}

Upvotes: 0

Views: 748

Answers (2)

pm100
pm100

Reputation: 50110

Correcting the obvious error

// Ptr = (char*)malloc(1000 * sizeof(char));

// read file contents till end of file
fread(&s1, sizeof(Record), 2, Ptr);

fclose(Ptr); /*close stream*/

the commented out line is clearly thinking it neeeds to 'allocate a buffer' in some way. No, s1 is the buffer, and you certainly never want to change Ptr (its the pointer to the internals of the file system).

However this code almost certainly wont work unless your file is very precisely laid out. For example it needs to start like this (in hex)

4141414100000000000000004242420000000000

if the fist name is "AAAA" and the first vendor is "BBB". And even then it might not work due to struct padding issues

Upvotes: 1

Guillaume Petitjean
Guillaume Petitjean

Reputation: 2718

Your code does not really make sense. Ptr points to the file opened through fopen which is fine. But then you allocate dynamic memory (through malloc) and assign the adress of this memory to the same Ptr. So basically you have lost the previous value of Ptr, in other terms the reference to your file (not to mention Ptr is of type FILE * and you assign to it a char *).

You don't need to allocate memory for Ptr, you need to allocate memory for the buffer where you copy data from this file. But here s1 is located on the stack, you don't need dynamic memory allocation.

Also be careful when copying raw data to a struct. Data structures may have "holes" in between their fields depending on data alignement (here as you have only chararrays, all the fields are probably contiguous).

I suggest you learn about data structures and the different kinds of memory allocation in C.

Upvotes: 0

Related Questions