0

I have written this function in C (function should receive a char*, allocate space necessary, and insert character given a pointer to the index of character behind the pointer)

void add_to_str(char *character, char ** string, int* index)
{
    //we dont expect  *string to be NULL !! no condition done
    if (*index == 0)    //if str is empty we will alloc AVGLEN(32) characters space
       *string=malloc(AVGLEN*sizeof(char));

    if (*string == NULL)   //malloc fails?
    {
        fprintf(stderr,errors[MALLOC]);
        exit(99);
    }
    //string length exceeds 32 characters we will allocate more space
    if ( *index > (AVGLEN-1) || character== NULL )// or string buffering ended, we will free redundant space
    {
        *string=realloc(*string,sizeof(char)*((*index)+2));//+1 == '\0' & +1 bcs we index from 0
        if (*string==NULL)   //realloc fails?
        {
            fprintf(stderr,errors[REALLOC]);
            exit(99);
        }
    }
    *string[(*index)++]=*character;
}

When *index > 0, it gives me a segmentation fault on the line

*string[(*index)++]=*character;

A variant of this function (just malloc behind char* and then assign characters to string[i++]) works perfectly.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
Smarty77
  • 1,208
  • 3
  • 15
  • 30
  • I suggest moving any `++` and such inside any non-trivial expressions to their own statements. Compiler should still produce same output after optimizations, and you may avoid some unexpected behavior and have clearer code. – hyde Oct 22 '13 at 20:16

3 Answers3

3

You have to be careful with this statement:

*string[(*index)++]=*character;

Because array indexing has higher precedence than pointer dereferencing. Thus, this is the same as

*(string[(*index)++]) = *character;

Which is not what you want. You want this:

(*string)[(*index)++] = *character;

The faulty code works for *index == 0 because in that case the statement is equivalent to **string, which is still valid, but when index > 0, string is going to be dereferenced in an invalid position: string+index.

Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70
0

Note that doing something like this:

ptr = realloc(ptr, ...);

is a really bad pattern. When realloc() fails your old allocated area is no longer accessible to the program and becomes leaked. The correct pattern would be:

char* str_new = realloc(string, ...);

if (str_new != NULL)
    string = str_new;
else
    /* handle allocation error */
Alexander L. Belikoff
  • 5,698
  • 1
  • 25
  • 31
  • yeah i see now, btw in this program certainly its true that i dont need the rest of a string when reallocation fails, but at least i can free() it carefully, thanks :) – Smarty77 Oct 22 '13 at 21:38
0

For a start the function fprintf requires a format string.

I.e.

 fprintf(stderr,errors[MALLOC]);

is probably invalid.

Also what is the purpose of this function. Seems to have no narrative,

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • btw it works errors* is a form of associative string array (smt like this)const char* const errors[] = { [MALLOC] = "ERROR: Malloc()'s dynamic memory alocation failed\n" } – Smarty77 Oct 22 '13 at 21:40