Reputation: 27
I am initializing a struct called Array which consists of an array of Items and an int to keep track of the number of the Items.
typedef struct anything{
char text[MAXI];
int any;
}Item;
typedef struct array{
Item arr[0];
int size;
}Array;
To initialize the Array, I'm using malloc and returning the pointer.
Array create(){
Array *p1 = malloc(sizeof(Array));
p1->size = 0;
return *p1;
}
The problem I have is that some functions are designed for 2 Arrays, such as intersection:
Array intersection(Array S,Array T){
int i, j;
Array I = create();
for(i=0; i<(S.size); i++){
for(j=0; j<(T.size); j++){
if((compStructs(S.arr[i], T.arr[j])) == true)
add(I, S.arr[i]);
}
}
return I;
}
According to this code, if I were to execute create() twice, I would lose the pointer to the first array. Is there something I can do in the main program to prevent this, or what modifications can I do to the current function?
Edit: Added the add item function:
void add(Array S,Item x){
bool rep = false;
int i = 0;
for(i = 0; i<(S.size); i++){
if(compStructs(x,S.arr[i]) == true)
rep = true;
}
if(rep == false){
Item *p2 = realloc(S.arr, sizeof(Item));
*p2 = x;
(S.size)++;
}
else
printf("The item is already in the set.");
}
My main problem is that I'm not sure how to call two seperate arrays which are to be created at the user's request. The program is in it's build up but currently it looks somehitng like this:
#include "array.h"
Item x;
void arraymenu(){
char inp;
while((inp = getchar())!= '\n'){
printf("a. To Create a new Array\n"
"b. To Add a new Item\n"
"c. To Remove an Item\n"
"d. To Clear all contents of the Array\n"
"e. To Get the size of the Array\n"
"f. To Get a list of the number of elements of your choice\n"
"g. To Check whether the array is empty\n"
"h. To Get the union of two sets\n"
"i. To Get the intersection of two sets\n"
"j. To Get the difference of two sets\n"
"k. To Check if a set is the subset of the other one\n"
"l. To map a function to all Items of an Array\n"
"m. To apply a function to all Items of an Array\n"
"n. To store the Array in a File\n"
"o. To load the Array from a File\n" );
switch(inp){
case 'a' : printf("Array A has been created.");
Array A = create();
break;
case 'b' : printf("Enter any integer, followed by any string.");
scanf("%d", &x.any);
scanf("%s", &x.text);
add(A, x);
break;
case 'c' : printf("Enter the integer and string you wish to remove ");
scanf("%d", &x.any);
scanf("%s", &x.text);
removee(A,x);
break;
}
}
}
Upvotes: 0
Views: 883
Reputation: 76433
Basically, instead of a derefferenced pointer to a variable local to a given function's scope you need to return a pointer (BTW, compiling return *ptr
should give a warning when compiling, add -Wall
, and don't ignore what the compiler is telling you):
Array *create()
{
Array *a_ptr = malloc(sizeof(*a_ptr));
if (a_ptr == NULL) exit (EXIT_FAILURE);//failed to allocate memory
a_ptr->size = 0;
return a_ptr;
}
To be called like this:
Array *S, *T;
S = create();
T = create();
Now you have 2 arrays ready to play with. Note that you'll need to either dereference these pointers, or use the indirection operator on them always:
(*S).size = 1;
//or
S->size += 123;
You'll also probably want to change intersection
to something like:
Array *intersection(Array *S,Array *T)
{
int i, j;
Array *I = create();
for(i=0; i<(S->size); ++i)
{
for(j=0; j<(T->size); ++j)
if(compStructs(S.arr[i], T.arr[j])) add(I, S.arr[i]);
}
}
return I;
}
Of course, once you're done with all of these Array
structs, you'll have to free()
them, too.
As far as compStructs
and add
go, I expect you'll have to work on those functions, too. While you're at it, perhaps change the struct to better fit the way you're using it:
typedef struct array
{
Item *arr;
size_t size;//size_t makes more sense here
}Array;
Of course, this in turn requires a bit more work when free
-ing the memory, so a generic free function is advisable:
void free_array(Array **a)
{//pointer to pointer
while((*a)->size--) free((*a)->arr+(*a)->size);
free(*a);
*a = NULL;//NULL pointers are safer
}
//call like so:
free_array(&Array_ptr);//yes, address of pointer
And realloc
calls should look something like:
realloc(a->arr, (a->size + 1)*sizeof(*(a->arr)));
a->size += 1;
Upvotes: 1
Reputation: 40145
typedef struct array{
int size;
Item arr[];
}Array;
Array *create(int size){
Array *p1 = malloc(sizeof(Array) + size*sizeof(Item));
if(p1)p1->size = size;
//return *p1;//memory leak
return p1;
}
Upvotes: 1