Reputation: 25
I searched quite a bit and I found similar problems but I still couldn't fix my issue. I want to allocate memory for an array of pointers to tables (each table has its own linked list) I hope I explained the idea properly, here's the code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Meal
{
struct Meal* next;
char* productname;
int price;
int quantity;
}Meal, * PMeal;
typedef struct Table //each table is supposed to have its own linked list of meals
{
PMeal next;
PMeal prev;
int tableNumber;
int cheque;
}Table;
typedef struct allTables
{
int maxoftables;
Table** tarray;
int numberoftables;
}allTables;
This is how I'm trying to dynamically allocate the array of pointers to tables:
(I think that this part is correct, it doesn't crash)
allTables tables;
tables.tarray = (Table**)malloc(sizeof(Table*) * tables.maxoftables)
Note: tables.maxoftables is initialized before the call to malloc, it's the maximum number of tables
And this is how I'm trying to initialize the linked lists in each table:
(This is where it tells me "Access violation writing location")
for (i = 0; i < tables.maxoftables; i++)
{
(tables.tarray[i])->cheque = 0;
(tables.tarray[i])->next = NULL;
(tables.tarray[i])->prev = NULL;
(tables.tarray[i])->tableNumber = i + 1;
}
I believe I could just allocate an array of struct Table but that is not allowed.
I hope everything that is needed for you to help me is here and that it's explained properly
Thanks!
Upvotes: 1
Views: 90
Reputation: 1996
Your code sample is nearly complete. The allocation reserves proper space for N pointers, but what do they point to? The memory range from malloc() is uninitialized and could be random/leftover data. A calloc() will both allocate memory and clear the range to zeros; the result is that all your table pointers would be NULL. That also makes it easy to spot bad pointers when you encounter runtime exceptions.
If calloc() was used and later when .cheque was assigned (or other struct members), the target address when writing to memory would start with the struct pointer (NULL) plus an offset of X bytes for the struct member:
// pseudo code
(NULL + small-byte-offset) <-- 0
The first page of virtual memory can be referred to as "zero page". Within your user program, most often zero page is intentionally left unmapped and useful for debugging cases like this.
While an array of table pointers was sufficiently allocated, they don't point to any valid memory. You'd also need to allocate .maxoftables structures and reference those with your allocated pointers.
It's unfortunate that allocating a struct array is somehow disallowed since it's fast/cheap to allocate an array with one request. Instead, you'd have to resort to inefficient means like this: allocate a Table structure plus check and assign the alloc result for each element of the pointer array.
Side note when allocating with calloc() : since all your struct members will be zero, that leads to a side-benefit where only 1 struct member from your example would need to be initialized (i + 1).
Upvotes: 1