-1

So i'm trying to figure out how to do a few different things and I haven't worked with C that much, so any help would be much appreciated.

typedef int data_t;

typedef struct set {
    data_t *array;
    size_t capacity;
    size_t size;
} set_t;

typedef data_t* set_i_t;

#define CLEAR -1

I have gotten this method working which uses malloc and allocates memory:

int set_init( set_t *set, int capacity ){

set->array = (data_t*)malloc(capacity * sizeof(data_t));

if(set->array == NULL){
    return 1;
}
else{
    set->capacity = capacity;
    set->size = 0;
    return 0;
}
}

And a method which frees it:

void set_free( set_t *set ){

free(set->array);
set->array = NULL;
set->capacity = set->size = 0;

}

In a separate method i'm trying to set all the values in the set to -1 (CLEAR)

void set_clear( set_t *set){

    int i = 0;

    for (i = 0; i < set->size; i++){
        set->array = CLEAR;
    }
    set->size = 0;

}

Return the Size of the set:

int set_size( set_t set ) {
    return sizeof(set->array);
}

Return the capacity:

int set_capacity( set_t set ) {
    int capacity = set->capacity;
    return capacity;
}

And then print the set:

void set_print( set_t set ) {
 //Honestly don't feel like i'm ready for this one yet.
}

If anyone could walk me through a couple of these or give me a little assistance on how these can work, that would be awesome. Thanks guys!

9
  • 1
    What exactly is your question? Which part of it do you need help with and what specifically are you having trouble with? Stackoverflow is not a tutorial site and works best with specific questions. Commented Mar 17, 2016 at 22:55
  • does it compile (I can see errors but wondered how far you have got). Remember that in 99% of cases warnings are errors Commented Mar 17, 2016 at 22:55
  • 1
    set::array is a pointer not an array. If you want it to be dynamically-sized you have to malloc() some space for it. If you don't, you should make it a fixed-sized array instead. Commented Mar 17, 2016 at 22:57
  • If you're going to clear the values in the set, why only those that correspond to set->size, rather than set->capacity? Also, set_clear() doesn't clear the elements of the set->array, it changes the pointer itself, which is probably not what you want. Commented Mar 17, 2016 at 22:58
  • 1
    Some more, your set_clear() function overwrites the pointer repeatedly, instead of the data it's pointing to. It's not really clear whether you want to overwrite it or free it. set_size() returns the size of the pointer, 8 bytes on amd64 or 4 bytes on i386. It's almost certainly not what you intend. set_capacity() is just plain weird. Commented Mar 17, 2016 at 23:02

2 Answers 2

0

A good resource is C dynamically growing array

1


You can read about size_t. What is size_t in C?

typedef int data_t; 
// Here you are redefining int to data_t this is then used in array.

typedef struct set {
    data_t *array;
// The address on heap where the typedef data_t is stored
    size_t capacity;
    size_t size;
} set_t;

typedef data_t* set_i_t; 
// not sure why this is here maybe you use somewhere else

#define CLEAR -1

2


set_free( set_t *set); Looks good to me.

set_init(); yes but no

set_t set_init(int capacity) {
    // create it here then return it.
    set_t ret;
    ret.array = (data_t*)malloc(capacity * sizeof(data_t));
    if (ret.array == NULL) return NULL;
    ret.capacity = capacity;
    ret.size = 0;
    return ret;
}

In the calling function

set_t A = set_init(5); 
if (A == NULL) fprintf(stderr, "could not alloc memory\n");
// :)

3


void set_clear( set_t *set){
    // you pass the address of the struct into the function. you could also use set_i_t

    //int i = 0; 
    // why do this you can do it in the for loop as you can see

    // for (i = 0; i < set->size; i++){
    for (int i = 0; i < set->size; i++){
        //set->array = CLEAR; common mistake
        // you are saying the address of the array. aka array[0]
        // this is the same as set->(array+i)
        set->array[i] = CLEAR;
    }
    set->size = 0;    
}

4 & 5


// looks good but again better ways of doing this.
set_size( set_t set ); 
set_capacity( set_t set ); 

Better ways of managing memory such as in the example here. C dynamically growing array

6

read all about printf(); http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm


void set_print( set_t set ) {
    // Here you passed the struct in plain and simple no pointer......
    // so you will use the '.' not the '->'
    // Here we can take a look at printf();
    // %d is used to print int variables.
    // to start off you know you will have to loop through the array.
    for (int i = 0; i < set.size; i++) {
        // you know the array must be at least have one item in it.
        printf("%d\n", set.array[i]);
        // using printf print the data_t aka "int" item in the array
    }
}

Hope this helps. G

Sign up to request clarification or add additional context in comments.

1 Comment

I really appreciate how you didn't necessarily give me the answer, but helped guide me towards it.. I appreciate this so much! Thanks again.
0

There were a few places where you defined the function arguments with set_t instead of set_t *.

Your set_size would just return the size of the array pointer (i.e. always 4 or 8), so that needed set->size

Also, set_clear was incorrect [and wouldn't even compile].

I've added some functions and implemented the [dreaded :-)] print function. No worries ...

Anyway, here's the corrected code [please pardon the gratuitous style cleanup]:

#include <stdio.h>
#include <malloc.h>

typedef int data_t;

typedef struct set {
    data_t *array;                      // pointer to set's data
    size_t capacity;                    // total number of data slots
    size_t size;                        // number of slots currently in use
} set_t;

typedef data_t *set_i_t;

#define CLEAR -1

int
set_init(set_t *set, int capacity)
{

    set->array = (data_t *) malloc(capacity * sizeof(data_t));

    if (set->array == NULL) {
        return 1;
    }
    else {
        set->capacity = capacity;
        set->size = 0;
        return 0;
    }
}

// And a method which frees it:
void
set_free(set_t *set)
{

    free(set->array);
    set->array = NULL;
    set->capacity = set->size = 0;

}

// i'm trying to set all the values in the set to -1 (CLEAR)
void
set_clear(set_t *set)
{

    int i = 0;

    for (i = 0; i < set->size; i++) {
#if 0
        set->array = CLEAR;
#else
        set->array[i] = CLEAR;
#endif
    }
    set->size = 0;

}

// Return the Size of the set:
int
set_size(set_t *set)
{
    return set->size;
}

// Return the maximum capacity:
int
set_capacity_max(set_t *set)
{
    int capacity = set->capacity;

    return capacity;
}

// Return the remaining available capacity:
int
set_capacity_avail(set_t *set)
{
    int capacity = set->capacity - set->size;

    return capacity;
}

// add some data
void
set_append(set_t *set,int val)
{

    // NOTES:
    // (1) this does _not_ check for overflow against capacity
    // (2) when out of capacity, we might increase capacity and do a realloc
    //     on array
#if 0
    if ((set->size + 1) >= set->capacity) {
        set->capacity += 100;
        set->array = realloc(set->array,sizeof(data_t) * set->capacity);
    }
#endif

    set->array[set->size++] = val;

}

// And then print the set:
void
set_print(set_t *set)
{
    int i;
    int len;

    // Honestly don't feel like i'm ready for this one yet.
    // Relax, no worries ...

    len = 0;
    for (i = 0; i < set->size; i++) {
        len += printf(" %d",set->array[i]);
        if (len >= 72) {
            printf("\n");
            len = 0;
        }
    }

    if (len > 0)
        printf("\n");
}

int
main(void)
{
    set_t myset;

    set_init(&myset,100);

    set_append(&myset,17);
    set_append(&myset,23);
    set_append(&myset,37);

    set_print(&myset);

    set_free(&myset);

    return 0;
}

2 Comments

This is unbelievably helpful you have no idea.
You're quite welcome. I find [and other OPs have told me] that full corrected code makes for the best teaching method. You were on the right track to begin with, anyway. BTW, I forgot to mention to always compile with -Wall -Werror. This can save lots of time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.