-1

I'm looking to realloc a double char array without free string in it, here is my code :

char **rea_scd_array(char **src, int add)
{
    char **ret;
    int  i;

    i = 0;
    while (src[i] != '\0')
        i++;
    ret = (char**) malloc(sizeof(char*) * (i + add + 1));
    ret[i + add] = '\0';
    while (i >= 0)
    {
        ret[i] = &src[i][0];
        i--;
    }
    free(&src);
    return (ret);
}

My idea is to add new dimension to store string in it without realloc all table of the array and duplicate all old content.

My code isn't working, I get

`"malloc: *** error for object 0x7fff5fbff9e8: pointer being freed was not allocated
 set a breakpoint in malloc_error_break to debug"`

I'm just looking to free the second array dimension who store pointer to string.

Any idea ?

DevSolar
  • 67,862
  • 21
  • 134
  • 209
insidelulz
  • 167
  • 1
  • 2
  • 11
  • 1
    Good English but horrible indentation.. – Maroun Mar 11 '14 at 10:31
  • 1
    Your English is not that bad. :) – Raghu Srikanth Reddy Mar 11 '14 at 10:32
  • [Please don't cast the return value of `malloc()` in C](http://stackoverflow.com/a/605858/28169). – unwind Mar 11 '14 at 10:36
  • Style hints: 1) Set your editor to use four spaces instead of tabs for indenting. Tabs are *asking* for trouble. 2) *Always* use `{}` for the body of `if` or `while`, even if it's a single line. 3) Don't cast the return value of `malloc()`. – DevSolar Mar 11 '14 at 10:36
  • My idea is to NOT realloc all the array, realloc is heavy – insidelulz Mar 11 '14 at 10:41
  • Your description is extremely vague and unclear. There are two plausible options to what you are trying to do: 1. Take a an array of characters and extend it to contain more characters. 2. Take a an array of strings and extend it to contain more strings. Your entire code is wrong in either case. BTW, in both cases, you can simply use `realloc`. – barak manos Mar 11 '14 at 10:49
  • Im looking to exetend a array of strings to contain more strings! I cannot use realloc! forget it. My idea is to make a realloc like without dumping string, I want to use string address not to copy string – insidelulz Mar 11 '14 at 10:56
  • free(&src); Did you mean free(src)?? – Varvarigos Emmanouil Mar 11 '14 at 11:14

3 Answers3

2

You are trying to free src to which you never allocated memory, in the first place. You free the memory that you allocated dynamically to the heap (typically through malloc).

Arjun Sreedharan
  • 11,003
  • 2
  • 26
  • 34
1

Your implementation compels you to add a NULL pointer at the end of the array.

The following lines of code are making me doubt that this is what you meant to do:

while (src[i] != '\0')
ret[i + add] = '\0';

If it was NULL instead of '\0' then I would think otherwise (although they are essentially identical).

In addition to that, using add larger than 1 will get you an array which contains some "junk pointers".

Anyway, at this point we have two options (excluding realloc):

  1. Use a NULL pointer in order to indicate the end of the array.
  2. Use a len variable in order to indicate the length of the array.

The second option is more efficient, so you would be better off with that.

Option #1:

char **rea_scd_array(char **src, int add)
{
    char **ret;
    int  i;
    int  len = 0;
    while (src[len] != NULL)
        len++;
    ret = (char**) malloc(sizeof(char*) * (len + add + 1));
    for (i=0; i<len; i++)
        ret[i] = src[i];
    for (; i<len+add+1; i++)
        ret[i] = NULL; // necessary in order for this function to work correctly
    free(src);
    return ret;
}

Option #2:

char **rea_scd_array(char **src, int len, int add)
{
    char **ret;
    int  i;
    ret = (char**) malloc(sizeof(char*) * (len + add));
    for (i=0; i<len; i++)
        ret[i] = src[i];
    for (; i<len+add; i++)
        ret[i] = NULL; // necessary for other functions that are using this array
    free(src);
    return ret;
}

In both cases, you'll need to allocate the initial array and fill it with NULL pointers, outside this function.

barak manos
  • 29,648
  • 10
  • 62
  • 114
0

If you dont know the size beforehand and you don't want to realloc, use a singly linked list:

#include <stdio.h>
#include <stdlib.h>

typedef struct node {
    char *data;
    struct node *next;
} t_node;

extern char *strdup(const char *);

t_node *insert(t_node *node, char *s)
{
    t_node *new = malloc(sizeof(*new));

    if (new == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    new->data = strdup(s);
    if (new->data == NULL) {
        perror("strdup");
        exit(EXIT_FAILURE);
    }
    new->next = NULL;
    if (node != NULL) node->next = new;
    return new;
}

int main(void)
{
    t_node *temp, *first, *node = NULL;

    node = first = insert(node, "First");
    node = insert(node, "Second");
    node = insert(node, "Third");
    node = insert(node, "Last");
    node = first;
    while (node) {
        printf("%s\n", node->data);
        temp = node->next;
        free(node->data);
        free(node);
        node = temp;
    }
    return 0;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94