Hi,

I have a struct that contains many different datatypes including arrays of other stucts, ints, floats, chars, char arrays etc. I have dynamically declared a ptr to the struct in main. I then pass the ptr deep into my functions and sub functions.

It is a struct that holds gym program info. My program can write/load/save this data.

Question - I would like to know how I can reset the struct that my ptn points to.. that way if a smaller program is loaded there is no left over data in the struct from the previous program?

I have been reading about memset but my understanding is it will not work for a struct.

Can anyone offer some advice?

Thanks.

Recommended Answers

All 8 Replies

@nateuni: I have been reading about memset but my understanding is it will not work for a struct.

I think memset is the way to go. You do not have many alternatives.

@nateuni: I have been reading about memset but my understanding is it will not work for a struct.

I think memset is the way to go. You do not have many alternatives.

Yes. I agree. Here's a sample of code I posted about a month ago to another member asking a similar question.

#include <stdio.h>
#include <string.h>

struct employee {
    char name[25];
    char doj[25];
    int empid;
};

void init_emp(struct employee *);

int main(void) {

    struct employee e[3];
    FILE *fp;
    int i, num;
    int k = 0;

    /*Read the details of three employees */
    fp = fopen("empfile.txt", "w");

    for (i = 0; i < 3; i++) {
        init_emp(&e[i]);
        printf("Enter the empid,name and doj: ");
        scanf("%d %s %s", &e[i].empid, e[i].name, e[i].doj);
    }

    //write all three records to the file
    fwrite(&e, sizeof(struct employee), 3, fp);

    fclose(fp);

    //read all three records from the file
    fp = fopen("empfile.txt", "r");
    fread(&e, sizeof(struct employee), 3, fp);

    printf("\nEnter the emp id to see the details\n");
    scanf("%d", &num);
    for (i = 0; i < 3; i++) {
        if (e[i].empid == num) {

            printf("Employee id = %d\nName = %s \nDate of joining = %s\n",
                    e[i].empid, e[i].name, e[i].doj);
        }
    }
    fclose(fp);
    return 0;
}

void init_emp(struct employee *e) {

    const int blank = 0x20;

    memset(e->name, blank, sizeof(struct employee) - sizeof(e->empid));
    //memset(e->name, blank, sizeof(e->name));
    //memset(e->doj, blank, sizeof(e->doj));
    e->empid = 0;
}

I provided some alternatives in the init_emp() function on different ways the struct could be initialised - that's the reason for the couple of lines that are commented out.

The code is functional as posted, so try it out and see if it suits your requirements.

I have been reading about memset but my understanding is it will not work for a struct.

There is nothing about a struct that causes memset() to fail, the problem is with the member types. memset(pobj, 0, n) will set n bytes starting at pobj to all bits 0. All bits 0 is not a guaranteed representation for most of the data types in C. It works for the character types and the exact width types from C99, but every other type can have trap representations from the padding bits for all bits zero that can halt a program. You described your struct as having more than the safe types, so memset() is not a safe option for the struct as a whole. The best you can do portably is manually assign values to each member and wrap it in a function for convenience.

There is nothing about a struct that causes memset() to fail, the problem is with the member types. memset(pobj, 0, n) will set n bytes starting at pobj to all bits 0. All bits 0 is not a guaranteed representation for most of the data types in C. It works for the character types and the exact width types from C99, but every other type can have trap representations from the padding bits for all bits zero that can halt a program. You described your struct as having more than the safe types, so memset() is not a safe option for the struct as a whole. The best you can do portably is manually assign values to each member and wrap it in a function for convenience.

I thought that was the intention of the code I posted - taking into account that I did not provide code based on the CCSID that the code would be accounting for with regards to the data it operates on. For the purposes of this forum, ASCII tends to be a reasonably safe bet.

Regards,
The "fake expert"

I thought that was the intention of the code I posted

Your code is fine, but I read nateuni's question as wanting to do something like this:

struct Program
{
    char a[SIZE];
    float b;
    char c;
    int d;
    struct Applicants e;
    struct Program* next;
};

void ClearProgram(Program* prog)
{
    // unsafe
    memset(prog, 0, sizeof *prog);
}

I thought it was important to make the distinction. :)

Fair enough. My code was an answer aimed at a specific query asked by another forum member.

There is nothing about a struct that causes memset() to fail, the problem is with the member types. memset(pobj, 0, n) will set n bytes starting at pobj to all bits 0. All bits 0 is not a guaranteed representation for most of the data types in C. It works for the character types and the exact width types from C99, but every other type can have trap representations from the padding bits for all bits zero that can halt a program. You described your struct as having more than the safe types, so memset() is not a safe option for the struct as a whole. The best you can do portably is manually assign values to each member and wrap it in a function for convenience.

Ok nice clarification, thanks that made sense.

Fair enough. My code was an answer aimed at a specific query asked by another forum member.

Though Tom Gunn's explanation was clearer, I appreciate you taking the time to help me out there.

Regards,
Nate

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.