sergeyrar sergeyrar - 3 months ago 9
C Question

Unable to initialize an array of structs

I'm trying to initialize array cells of type struct using memset.
The program successfully compiles, however Valgrind is not happy with something related to memseting those cells.
The commented-out code doesn't work either.

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define MAX_DATA 512
#define MAX_ROWS 100



struct Address {
int id;
int set;
char name[MAX_DATA];
char email[MAX_DATA];
};

struct Database{
struct Address rows[MAX_ROWS];
};

struct Connection{
FILE* file;
struct Database* db;
};


void die(const char* message)
{
if(errno){
perror(message);
}else{
printf("ERROR: %s\n", message);
}
exit(1);
}



void Database_load(struct Connection* conn)
{
int rc = fread(conn->db, sizeof(struct Database), 1, conn->file);
if (rc != 1)
{
die("Failed to load database.");
}
}


struct Connection* Database_open(const char* filename, char mode)
{
struct Connection* conn = malloc(sizeof(struct Connection));
if (!conn)
{
die("Memory error");
}

if (mode == 'c')
{
conn->file = fopen(filename, "w");
}
else
{
conn->file = fopen(filename, "r+");

if(conn->file) {
Database_load(conn);
}
}

if(!conn->file) die("Failed to open file");
return conn;
}


void Database_create(struct Connection* conn)
{
int i = 0;

for(i = 0; i < MAX_ROWS; i++) {
//struct Address addr = {.id = i, .set = 0};
//conn->db->rows[i] = addr;
memset(&(conn->db->rows[i]), 0, sizeof(struct Address));
conn->db->rows[i].id = i;
}
}




int main(int argc, char* argv[])
{
if(argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]");

char* filename = argv[1];
char action = argv[2][0];
struct Connection* conn = Database_open(filename, action);
int id = 0;
if(argc > 3) id = atoi(argv[3]);
if(id >= MAX_ROWS) die("There's not that many records.");


Database_create(conn);

return 0;
}


related Valgrind error -

==16227== Conditional jump or move depends on uninitialised value(s)
==16227== at 0x4C3009C: memset (vg_replace_strmem.c:1224)
==16227== by 0x400BA8: Database_create (ex17.c:108)
==16227== by 0x400EE1: main (ex17.c:174)

Answer

Your code never initializes conn->db

You need something like:

conn->db = malloc(sizeof(struct Database));
if (!conn->db) 
{
    die("Memory error");
}

inside the Database_open function