Populating a structure I'm solving K&amp;R exercise 1-13:


  Write a program to print a histogram of the lengths of words
  in its input. It is easy to draw the histogram with the bars horizontal; a 
  vertical orientation is more challenging.


Although the exercise itself is pretty simple, I've decided to apply a more "professional" approach and encapsulate (is that a correct word?) histogram into a structure:

typedef struct {
    /* Legend and character to 'draw' histogram with */
    char **legend, chr;
    /* Histogram data */
    int *data;
    /* Max. data value, bin width, space between bins, max. bin length */
    int datamax, binwidth, binmargin, binlength;
    /* Data and legend array lengths */
    size_t datasize, legendsize;
} chart_t;


Because it's still a toy program, I decided to not overcomplicate algorithm so my histogram is limited to only integer data (it's hard to represent floating point values graphically in console anyway).

Overall algorithm works more or less correctly, so I ask to review only my chart creation procedure. The whole point of this was to learn how to use dynamic memory (allocate, free, etc.).

#define BINWIDTH_DEFAULT 3
#define BINMARGIN_DEFAULT 1
#define BINLENGTH_DEFAULT 14

/* ... */

chart_t *create_chart(int *data, size_t ds, char **lgnd, size_t ls, char chr) {
    chart_t *out = (chart_t *) malloc(sizeof(chart_t));

    if(out == NULL)
        return NULL;

    out-&gt;chr = chr;
    out-&gt;datasize = ds;
    out-&gt;legendsize = ls;

    out-&gt;binwidth = BINWIDTH_DEFAULT;
    out-&gt;binmargin = BINMARGIN_DEFAULT;
    out-&gt;binlength = BINLENGTH_DEFAULT;

    out-&gt;data = (int *) calloc(ds, sizeof(int));

    if(out-&gt;data == NULL) {
        free(out);
        return NULL;
    }

    memcpy(out-&gt;data, data, ds);

    int dmax = 0;
    for(int i = 0; i &lt; ds; i++)
        if(data[i] &gt; dmax)
            dmax = data[i];

    out-&gt;datamax = dmax;

    char **legend = (char **) calloc(ls, sizeof(char *));

    for(int i = 0; i &lt; ls; i++) {
        size_t len = strlen(lgnd[i]);

        if(len == 0)
            continue;

        char *curstr = (char *) calloc(len+1, sizeof(char));

        if(curstr == NULL) {
            if(i &gt; 1)
                for(int j = 0; j &lt; i; j++)
                    free(legend[j]);

            free(legend);
            free(out);

            return NULL;
        }

        strncpy(curstr, lgnd[i], len+1);

        legend[i] = curstr;
    }

    return out;
}


Haven't I missed anything? Do I have any potential memory problems in my procedure?
A case cursor == NULL does not free(out-&gt;data).
A test i &gt; 1 is strange, and buggy. If i happens to be 1, you are leaking memory legend[0] points to.
Do not cast the result of malloc
Calling calloc in char *curstr = (char *) calloc(len+1, sizeof(char)); is an overkill:


sizeof(char) is guaranteed to be 1, and
the contents of curstr is immediately overwritten by strncpy, so its zero initialization was a waste of time.

The body of the loop spells out

    legend[i] = strdup(lgnd[i]);


in a very obfuscated way.
Given no context, it is very hard to see why do you need all that dynamic allocation at all.