C array of pointers, casting and / or memory - c

I don't understand why these pointer values seem to be correct, but the values I am trying to get out of them are not. (I studied C a long time ago, and I am recently trying to get back into it for fun).
Here is a working example of the problem I am facing, but I am not sure what I am doing wrong - am I casting the pointers incorrectly, not correctly managing memory, or something else.
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#define Q_STACK_MAX 100
typedef struct
{
void* value[Q_STACK_MAX];
int top;
} Stack;
void push(Stack* S, void* val)
{
S->value[S->top] = val;
(S->top)++;
}
void* pop(Stack* S)
{
(S->top)--;
return (S->value[S->top]);
}
void init(Stack* S)
{
S->top = 0;
}
int full(Stack* S)
{
return (S->top >= Q_STACK_MAX);
}
void recursive_dir(char* dir, char* search, Stack* S)
{
DIR* dp;
struct dirent* entry;
struct stat statbuf;
if((dp = opendir(dir)) == NULL) {
fprintf(stderr, "error: %s\n", dir);
return;
}
chdir(dir);
while((entry = readdir(dp)) != NULL) {
lstat(entry->d_name, &statbuf);
if(S_ISDIR(statbuf.st_mode)) {
if(strcmp(".", entry->d_name) == 0 ||
strcmp("..", entry->d_name) == 0)
continue;
recursive_dir(entry->d_name, search, S);
} else {
if( strstr(entry->d_name, search) != NULL ) {
if(!full(S)) push(S, (void *)entry);
printf("%p\n", entry);
printf("%s [%x]\n", entry->d_name, entry->d_ino);
}
}
}
chdir("..");
closedir(dp);
}
int main() {
Stack S;
init(&S);
int i;
printf("\n");
recursive_dir("/etc/", "conf", &S);
printf("\n------------------------------\n");
int top = S.top;
struct dirent* entry;
for (i=0; i<top; i++)
{
//struct dirent* entry = (struct dirent*)pop(&S);
entry = (struct dirent*)S.value[i];
printf("%p\n", entry);
printf("%s [%x]\n", entry->d_name, entry->d_ino);
}
printf("\n");
return 0;
}
What this outputs are the pointer values to the dirent structures, the file name that is within that structure, and the file serial number. It then tries to cast the pointer to that direct to a (void*) and store it in a makeshift stack.
Later, I try to iterate over the values in the stack (well the array), cast it back to a dirent and then display the same information.
This works sometimes and doesn't work other times. A trimmed output example:
...
0x7ff831806360
httpd-multilang-errordoc.conf [2cb6e07]
0x7ff831806398
httpd-ssl.conf [2cb6e08]
0x7ff8318063c0
httpd-userdir.conf [2cb6e09]
0x7ff8318063ec
httpd-vhosts.conf [2cb6e0a]
0x7ff831805250
httpd.conf [2cb6e0b]
0x7ff831805274
httpd.conf~previous [187a3]
0x7ff831807230
httpd-autoindex.conf [2cb6e10]
0x7ff831807260
httpd-dav.conf [2cb6e11]
0x7ff831807288
httpd-default.conf [2cb6e12]
0x7ff8318072b4
httpd-info.conf [2cb6e13]
...
--------------------------
...
0x7ff831807360
httpd-multilang-errordoc.conf [2cb6e17]
0x7ff831807398
httpd-ssl.conf [2cb6e18]
0x7ff8318073c0
httpd-userdir.conf [2cb6e19]
0x7ff8318073ec
httpd-vhosts.conf [2cb6e1a]
0x7ff831806250
[0]
0x7ff831806230
320.whatis [2cb6ff6]
0x7ff8318042bc
asl.conf [2cb7d07]
0x7ff83180437c
autofs.conf [2cb6f5f]
0x7ff831805250
[0]
0x7ff831805274
??$ [61666564]
0x7ff8318052e0
_response [6e7261]
...
Sometimes everything seems correct, and other times the file handle and / or the name are completely wacked out.
Generally when I see something like that it is because I am not doing something with memory correctly - having lived in the garbage collection world for so long I wouldn't be surprised that was it, but I am not sure why or how.
Any help would be appreciated.
(I've been coding for quite a number of year, I've just been out of the C arena for quite a while. Please go easy on me.)

The dirent structure returned by readdir() can reuse memory on repeated calls. If you want to save them, you should either copy them into dynamic objects, or allocate the objects first and call readdir_r().

Related

How to access recursive structure with pointers

I am getting a really strange error in my C program and therefore I need your help guys! So I have a recursive structure called path, where sometimes I store the address of the "parent" path in the structure field mother:
typedef struct path{
struct path* mother;
struct path** children;
int length;
uint8_t* inf;
} path;
So in my example I just generate one path like this:
int child_num=2;
int bytes=10;
path* my_path=malloc(sizeof(path));
if (path==NULL) throw error...
my_path->inf=malloc(sizeof(uint8_t)*bytes);
memset(my_path->inf, 4, bytes);
my_path->children=malloc(sizeof(path*)*child_num);
for(int i=0; i<child_num; i++){
my_path->children[i]->mother=my_path;
my_path->children[i]->inf=malloc(sizeof(uint8_t)*bytes);
memset(my_path->children[i]->inf, 5, bytes);
}
So now since I stored the link to the parent structure, I want to use another helping pointer to get access to its information:
path* my_pointer=my_path->children[0]->mother; //this is just for the example
So i checked the addresses and everything seems to be alright, but if I know use the pointer in another method, pointing to the field "inf", it works if I use the variable "path" so:
method(path->inf, bytes);
it is fine, but as soon as I do:
method(my_pointer->inf, bytes);
the method crashes at the marked line:
void method(uint8_t* element, int bytes) {
if (element==NULL) ... //<=== here it crashes
//do something
}
I really dont get what I am doing wrong, I printed the addresses and everything seems to be good, even if I access a certain byte over the variable "my_pointer", so like
my_pointer->inf[1]
it returns me the corresponding value, but in the separate method it doesnt work.
Like the comments indicate we can't exactly answer your question with the information provided, but we can point you in the right direction.
First, I noticed in your examples that you're using path as a variable name to a typedef'd path structure. You need to either be more verbose with your variable names or actually copy paste some code to make sure that we can look at the actual problem, because it could simply be an issue with naming.
All in all I think it would do you a world of good to employ a bit of code hygiene. Organize some of the functions you use for data structure overhead at file scope:
static int path_alloc(path* p);
static int path_alloc_kids(path* p, int num);
static int path_alloc(path* p) {
if(p == NULL) { return -1; }
p = (path*)malloc(sizeof(path));
if(p == NULL) { return -2; }
return 0;
}
static int path_alloc_kids(path* p, int num) {
if(p == NULL || num <= 0) { return -1; }
if(!path_alloc(p)) { /* Easier to read and understand, no error handling here to muddle things up */
/* You don't actually need a path**, do you? Think of char *argv[] a.k.a. char **argv, is that what you're actually going for? */
p->children = (path*)malloc(sizeof(path) * num);
if(p->children == NULL) { return -2; }
p->length = num;
} else { return -1; } /* Simple */
return 0;
}
This makes it a LOT easier to understand your code, which is the main issue with pointers. Add in some methods to free the allocated children and roots and you're set to use this path structure in a relatively abstracted way. You may want to consider using a path and a path_node in a linked-list fashion, that way you only allocate what you need.
struct spath_node; /* So it knows of itself */
typedef struct spath_node {
struct spath_node *parent;
struct spath_node *next;
uint8_t *data;
int data_size;
} path_node;
Then allocate by passing in a data size and parent, a NULL parent could mean it's a root node.
static int path_alloc_node(path_node *parent, int data_size, uint8_t *data);
This makes for relatively slow insert/traversal, but easier to understand where you went wrong.
EDIT: To be clear, this is how we would add children to the linked-list example:
static int path_alloc_node(path_node *parent, int data_size, uint8_t *data) {
path_node *tmp;
if(parent == NULL || data_size <= 0) { return -1; }
if(parent->next != NULL) { return -3; }
tmp = (path_node*)malloc(sizeof(path_node));
if(tmp == NULL) { return -2; }
else parent->next = tmp;
if(data == NULL) { /* Assume the caller is requesting a new data block of the given size */
data = (uint8_t*)malloc((size_t)data_size);
if(data == NULL) { return -2; }
}
parent->next->data = data;
parent->next->data_size = data_size;
parent->next->next = NULL;
parent->next->parent = parent;
return 0;
}

C - Pointer to dynamic array in struct "Segmentation fault (core dumped)"

I'm writing a c program to read the files and directories from a directory and then point the number of elements found in a data of a struct and point the name of the elements in a dynamic array in a data of the same struct. I did it and its output is right. The problem is that when I run the program a "Segmentation fault (core dumped)" shows up.
The code:
#include <stdio.h>
#include <dirent.h>
#define EXIT_FAILURE 1
typedef struct FileDir
{
int *n_files;
char *file_name[];
} FileDir;
int get_files_within_dir(struct FileDir *fd)
{
DIR *dir;
int n_files;
int index;
n_files = 0;
if ((dir = opendir ("/tmp")) != NULL) {
/* counts all the files and directories within directory */
while (readdir (dir) != NULL) {
n_files++;
}
closedir (dir);
} else {
/* could not open directory */
perror ("");
return EXIT_FAILURE;
}
char *file_name[n_files];
struct dirent *ent;
if ((dir = opendir ("/tmp")) != NULL) {
/* gets all the files and directories within directory */
index = 0;
while ((ent = readdir (dir)) != NULL) {
file_name[index++] = ent->d_name;
}
closedir (dir);
} else {
/* could not open directory */
perror ("");
return EXIT_FAILURE;
}
fd->n_files = n_files;
fd->file_name[0] = file_name[0];
fd->file_name[1] = file_name[1];
fd->file_name[2] = file_name[2];
fd->file_name[3] = file_name[3];
return 0;
}
int main()
{
struct FileDir fd;
get_files_within_dir(&fd);
printf("%d\n", fd.n_files);
printf("%s\n", fd.file_name[1]);
printf("%s\n", fd.file_name[2]);
printf("%s\n", fd.file_name[3]);
return 0;
}
The output:
[freitas#localhost src]$ ./file_dir
21
..
geany_socket.fcda02b3
tmpiSdUX3
Segmentation fault (core dumped)
The interesting thing is that if I just point less than or equal to 2 values to the dynamic array of the data of the struct the error message does not show up. Do you have any idea ?
Thank you!
You have 2 problems, that can be causing the SEGMENTATION FAULT
The n_files field is a pointer, and you assigned an integer to it, it should be declared as
int n_files;
You don't ever allocate space for the file_name field, you should at least provide a fixed size, like this
char *file_name[1000];
you could allocate the memory dynamically using malloc() but that's another thing, and it requires explanation.
note: enabling compiler warnigns would help you prevent silly mistakes like int *n_files and then doing fd->n_files = n_files;.
n_files should not be a pointer
typedef struct FileDir
{
int n_files;
char *file_name[];
} FileDir;
Then your line
printf("%d\n", fd.n_files);
will not crash. Try looking at the struct with a debugger

pointer problems when trying to build a directory tree in memory

Problem 1: what's the best data structure to save the directory structure?
Problem 2: I have tried to use a general tree to solve it, but there are a lot of problems:
The number of files under a directory is not certain. So the number of child nodes under a tree node is also not certain. and I try to add a keyword nchild to each node, showing nchild child nodes. so there are nchild pointers (saved with **child) to the child nodes. And once that, **child and *child should be dynamically allocated space with no certain child nodes. So you know, this is really difficult to release these spaces(and the program below is not called free()). Is there a better way to solve it?
And sometimes the program below would get the garbage characters when I output the directory tree, which make me really confused. while debugging it, found that is the function ent=readdir(pDir); has read garbage characters. But when I write another simple program to read the same directory, that goes well. I think the problem is the recursive function, but I didn't get any idea. I will be appreciated if some one can give me a idea. Thanks!
```
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
typedef struct tree_file_s
{
char path[512];
time_t date;
char type;
long size;
int nchild;
struct tree_file_s **child;
} tree_file_t;
int dir_child_len(const char *dir)
{
int nchild = 0;
DIR *pDir;
struct dirent *ent;
pDir = opendir(dir);
while((ent=readdir(pDir)) != NULL)
{
if (strcmp(ent->d_name, ".")==0 || strcmp(ent->d_name, "..")==0)
{
continue;
}
nchild++;
}
return nchild;
}
void tree_create(tree_file_t *tft, const char *dir)
{
int nchild; // the tft has n child
DIR *pDir;
struct dirent *ent; // the directory dir dirent info
struct stat file_stat; // the new file's stat info
stat(dir, &file_stat);
nchild = dir_child_len(dir);
pDir = opendir(dir);
// Initialize the parent
//tft->path = calloc(1, strlen(dir)+1);
strcpy(tft->path, dir);
tft->date = file_stat.st_mtime;
tft->type = 'D';
tft->size = file_stat.st_size;
tft->nchild = nchild;
tft->child = calloc(1, nchild);
nchild = 0;
while ((ent=readdir(pDir)) != NULL)
{
if (ent->d_type & DT_DIR)
{
if (strcmp(ent->d_name, ".")==0 || strcmp(ent->d_name, "..")==0)
{
continue;
}
tree_file_t *new_dir = calloc(1, sizeof(tree_file_t));
tft->child[nchild] = new_dir;
char *new_path = calloc(1, strlen(dir)+strlen(ent->d_name)+1);
sprintf(new_path, "%s/%s", dir, ent->d_name);
tree_create(new_dir, new_path);
free(new_path);
} else {
tree_file_t *new_file = calloc(1, sizeof(tree_file_t));
char *new_path = calloc(1, strlen(dir)+strlen(ent->d_name)+1);
// new_file->path = calloc(1, strlen(dir)+strlen(ent->d_name)+1);
sprintf(new_path, "%s/%s", dir, ent->d_name);
stat(new_path, &file_stat);
strcpy(new_file->path, new_path);
free(new_path);
new_file->date = file_stat.st_mtime;
new_file->type = 'F';
new_file->size = file_stat.st_size;
new_file->nchild = 0;
new_file->child = 0;
tft->child[nchild] = new_file;
}
//free(new_path);
//new_path = 0;
nchild++;
}
}
void display_tree(tree_file_t *tft)
{
int nchild, i;
nchild = tft->nchild;
printf("%c: %s\n", tft->type, tft->path);
for(i = 0; i < nchild; i++)
{
if(tft->child[i]->type == 'F')
{
printf("%c: %s\n", tft->child[i]->type, tft->child[i]->path);
} else {
display_tree(tft->child[i]);
}
}
}
int main(int argc, const char *argv[])
{
if(argc != 2)
{
printf("Usage: a.out dir\n");
exit(0);
}
char dir[512];
strcpy(dir, argv[1]);
tree_file_t *tft = calloc(1, sizeof(tree_file_t));
tree_create(tft, dir);
display_tree(tft);
return 0;
}
```
When you allocate space for new_path you need to add 2 (one for the slash, one for the null terminator). And you never close the directories you open (use closedir()).
An even more serious error is this line:
tft->child = calloc(1, nchild);
which only allocates nchild bytes, not enough to hold nchild pointers! Try:
tft->child = calloc(nchild, sizeof(*tft->child));

Pointer being freed was not allocated, Abort trap: 6

I'm not proficient in C programming so please excuse me if this isn't a strong question. In the following code, I can only allocate memory to samplesVecafter obtaining the value of nsamplepts, but I need to return the vector samplesVec to the main for further use (not yet coded). However, I'm getting the following error:
Error in Terminal Window:
ImportSweeps(3497,0x7fff7b129310) malloc: * error for object 0x7fdaa0c03af8: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
Abort trap: 6
I'm using Mac OS X Mavericks with the gcc compiler. Thanks for any help.
*EDITED!!! AFTER VALUABLE INPUTS FROM COMMENTATORS, THE FOLLOWING REPRESENTS A SOLUTION TO THE ORIGINAL PROBLEM (WHICH IS NO LONGER AVAILABLE) *
The following code modification seemed to solve my original questions. Thanks for the valuable inputs everyone!
/* Header Files */
#define LIBAIFF_NOCOMPAT 1 // do not use LibAiff 2 API compatibility
#include <libaiff/libaiff.h>
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <math.h>
/* Function Declarations */
void FileSearch(char*, char*, char*, char*, char*);
int32_t *ImportSweeps(char*);
/* Main */
int main()
{
char flag1[2] = "N";
char binname[20] = "bin1"; // dummy assignment
char buildfilename[40] = "SweepR";
char skeletonpath[100] = "/Users/.../Folder name/";
int k, len;
/* Find the sweep to be imported in the directory given by filepath */
FileSearch(skeletonpath, binname, buildfilename, skeletonpath, flag1);
if (strcmp(flag1,"Y")) {
printf("No file found. End of program.\n");
} else {
len = (int) strlen(skeletonpath);
char *filepath = malloc(len);
for (k = 0; k < len; k++) {
filepath[k] = skeletonpath[k];
}
printf("File found! Filepath: %s\n", filepath);
// Proceed to import sweep
int32_t *sweepRfile = ImportSweeps(filepath);
if (sweepRfile) {
printf("Success!\n");
// Do other things with sweepRfile
free(sweepRfile);
}
free(filepath);
}
return 0;
}
/* Sub-Routines */
void FileSearch(char *dir, char *binname, char *buildfilename, char* filepath, char* flag1)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if((dp = opendir(dir)) == NULL) {
fprintf(stderr,"Cannot open directory: %s\n", dir);
return;
}
chdir(dir);
while((entry = readdir(dp)) != NULL) {
lstat(entry->d_name, &statbuf);
if(S_ISDIR(statbuf.st_mode)) {
/* Found a directory, but ignore . and .. */
if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0)
continue;
strcpy(binname,entry->d_name);
strcpy(buildfilename,"SweepR");
/* Recurse at a new indent level */
FileSearch(entry->d_name, binname, buildfilename, filepath, flag1);
}
else {
sprintf(buildfilename, "%s%s.aiff", buildfilename, binname);
if (strcmp(entry->d_name,buildfilename)) {
strcpy(buildfilename,"SweepR");
} else {
sprintf(filepath, "%s%s/%s", filepath, binname, buildfilename);
strcpy(flag1,"Y");
break;
}
}
}
chdir("..");
closedir(dp);
}
int32_t *ImportSweeps(char *filepath)
{
char *filepathread = filepath;
/* Initialize files for importing */
AIFF_Ref fileref;
/* Intialize files for getting information about AIFF file */
uint64_t nSamples;
int32_t *samples = NULL;
int32_t *samplesVec = NULL;
int channels, bitsPerSample, segmentSize, ghost, nsamplepts;
double samplingRate;
/* Import Routine */
fileref = AIFF_OpenFile(filepathread, F_RDONLY) ;
if(fileref)
{
// File opened successfully. Proceed.
ghost = AIFF_GetAudioFormat(fileref, &nSamples, &channels, &samplingRate, &bitsPerSample, &segmentSize);
if (ghost < 1)
{
printf("Error getting audio format.\n");
AIFF_CloseFile(fileref); return (int32_t) 0;
}
nsamplepts = ((int) nSamples)*channels;
samples = malloc(nsamplepts * sizeof(int32_t));
samplesVec = malloc(nsamplepts * sizeof(int32_t));
ghost = AIFF_ReadSamples32Bit(fileref, samples, nsamplepts);
if (ghost) {
for (int k = 0; k < nsamplepts; k++) {
samplesVec[k] = *(samples+k);
}
}
free(samples);
AIFF_CloseFile(fileref);
}
return samplesVec;
}
So... as far as I can see... :-)
samplesVec, the return value of ImportSweeps is not initialized, if fileref is false. Automatic (== local) variables have no guarantees on its value if samplesVec are not explicitly initialized - in other words samplesVec could carry any address. If samplesVec is not NULL on luck (which on the other hand might be often the case), you try free a not allocated junk of memory, or by very bad luck an somewhere else allocated one.
If I'm correct with my guess you can easy fix this with:
int32_t *samples;
int32_t *samplesVec = NULL;
It is a good idea anyway to initialize any variable as soon as possible with some meaningful error or dummy value, if you not use it in the very next line. As pointers are horrible beasts, I always NULL them if I don't initialize them with a useful value on declaration.
Edit: Several minor small changes for a readable approximation to English. :-)
If AIFF_OpenFile fails, ImportSweeps returns an undefined value because samplesVec wasn't initialized. If that value is non-NULL, main will try to free it. You can either initialize samplesVec = NULL, or you can reorganize the code as
fileref = AIFF_OpenFile(filepathread, F_RDONLY) ;
if(!fileref) {
{
// print error message here
return NULL;
}
// File opened successfully. Proceed.
...
There are people who will insist a functon that should only have one exit -- they are poorly informed and voicing a faulty dogma handed down from others who are likewise uninformed and dogmatic. The check for error and return above is known as a guard clause. The alternate style, of indenting every time a test succeeds, yields the arrow anti-pattern that is harder to read, harder to modify, and more error prone. See http://blog.codinghorror.com/flattening-arrow-code/ and http://c2.com/cgi/wiki?ArrowAntiPattern for some discussion.

Problems concerning pointers and malloc in C90

I am quite a newbie when it comes to C, and seem to be having a few issues when it comes to memory allocation and pointers. For my assignment, we have to create the ADT of dynamic sets using arrays, and to do this we require heavy use of pointers which I find a bit difficult to grasp.
I created a structure to act as the sets
struct Set{
int arrelement; //the 'size' of the array
int * arrvalue;; //the array
}
typedef struct Set *SetArray;
The issue arises when I come to applying functions such as Add(where I add a unique element to the set) or Cardinality (where the programs shows me the total number of elements in the set). Adding seems to crash my program after more than 2 additions and trying to retrieve the stored data supplies junk variables.
Here is the code for the relevant functions
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Array.h"
int size = 1; // similar to arrelement, to be used for realloc
SetArray Create(){ // to allocate memory for the set
SetArray sptr;
sptr = malloc(sizeof(struct Set));
sptr->arrvalue = malloc(sizeof(struct Set));
sptr->arrelement = 1;
return sptr;
}
SetArray Add(SetArray sptr, int x){
if(Is_Element_Of(x, sptr)){ //function to keep elements in set unique.
//Function works, which brings me to
//believe values are being stored
puts("Value already exists, enter a unique value");
}
else{
if(sptr == NULL){
puts("Memory Allocation Failed. Shutting down.");
exit(EXIT_FAILURE);
}
}
sptr = realloc(sptr, size*sizeof(struct Set)); //reallocate memory
//for the
//new element
sptr->arrvalue[sptr->arrelement] = x;
sptr->arrelement++;
size++;
return sptr;
}
SetArray Remove(SetArray sptr, int x){
if(sptr == NULL){
puts("Memory Allocation Failed. Shutting down.");
exit(EXIT_FAILURE);
}
else if(!Is_Element_Of(x, sptr)){
puts("Value is not in set");
}
else if(sptr->arrvalue == NULL){
puts("Set is empty. Cannot remove that which does not exist");
}
else{
sptr = realloc(sptr, size*sizeof(struct Set));
sptr->arrvalue[sptr->arrelement] = '\0';
sptr->arrelement--;
size--;
}
return sptr;
}
SetArray Clear(SetArray sptr){
if(sptr == NULL){
puts("Memory Allocation Failed. Shutting down.");
exit(EXIT_FAILURE);
}
int i;
for(i = 0; i < sptr->arrelement; i++){
sptr->arrvalue[i] = '\0';
}
return sptr;
}
Also, not sure if relevant, but just in case, here is the Function Is_Element_Of
int Is_Element_Of(int x, SetArray sptr){
if(sptr == NULL){
puts("Memory Allocation Failed. Shutting down.");
exit(EXIT_FAILURE);
}
int flag = 0;
int i;
for(i = 0; i < sptr->arrelement; i++){
if(sptr->arrvalue[i] == x){
flag = 1;
}
}
return flag;
}
Pardon me for any mistakes, but this is my first time asking and I tried my best to keep everything organized and structured properly.
Thank you for reading.
You are reallocating the wrong pointer you realloc the pointer to your parent Set when you want to realloc the array it contains.
sptr = realloc(sptr, size*sizeof(struct Set));
should be
sptr->arrvalue = realloc(sptr->arrvalue, (sptr->arrelement+1)*sizeof(int));
I guess your main problem is this :
sptr->arrvalue = malloc(sizeof(struct Set));
since arravlue is int*, try this :
sptr->arrvalue = malloc(sizeof(int));
edit: same for realloc

Resources