Thunderpurtz
Thunderpurtz

Reputation: 199

Why is my array holding garbage values/segfaulting after passing it into another function?

I have a function that mallocs an array to hold value to encode into. After the values are encoded into the integer array, that array itself gets passed by reference (at least thats the theory). However, I was getting garbage values when I compiled the function so I started throwing print statements everywhere to see what was going on. Right after the second function gets called and the array is passed, the I realize that the print statements are segfaulting, which is strange to me.

Primary function:

void    top_left_justify(char **pieces)
{
    int i;
    int j;
    int count;
    int *values; //array to be passed

    i = 0;
    if (!(values = (int *)malloc(sizeof(int) * 4)))
        return ;
    while (pieces[i] != 0)
    {
        j = 0;
        count = 0;
        while (pieces[i][j])
        {
            printf("count = %d\n", count);
            if (pieces[i][j] == '#')
                values[count++] = j;
            j++;
        }
        printf("encoded indexes are: %d, %d, %d, %d\n", values[0], 
values[1], values[2], values[3]); //test printout shows me it works here
        top_left_helper(&values, pieces[i]); //PASS BY REFERENCE??
        i++;
    }
}

However, after it gets passed into this function:

void    top_left_helper(int **values, char *pieces)
{
    int i;
    int j;

    i = 0;
    j = 0;
    printf("value of values[0] = %d\n", *values[0]); //prints correct value
    printf("value of values[0] = %d\n", *values[1]); //segfaults
    left_helper(&*values);
    top_helper(&*values);
    while (i < 16)
        pieces[i++] = '.';
    while (j < 4)
        pieces[*values[j++]] = '#';
}

It segfaults on the second print statement. I cannot really see an explanation for this other than my misunderstanding how passing parameters by reference and memory works. Please shed some light.

EDIT: After some testing, it seems if I print out values by incrementing the pointer instead of array access, I am able to properly access the values to print. But that doesn't make any sense to me still why an array access wouldn't work. (following lines were added in second function)

printf("value of values[0] = %d\n", **values);
*values = *values + 1;
printf("value of values[1] = %d\n", **values);
*values = *values + 1;
printf("value of values[2] = %d\n", **values);
*values = *values + 1;
printf("value of values[3] = %d\n", **values);

Upvotes: 2

Views: 47

Answers (1)

dbush
dbush

Reputation: 223689

This isn't doing what you think it is:

*values[1]

[] has higher precedence than *, so this first indexes values as an array, then dereferences the value it gets back. But what you passed into this function is a pointer to a variable which is also a pointer. So values[1] doesn't make sense. You get away with *values[0] because it's the same as **values What you want is:

(*values)[1]

However, unless you need to modify vaules itself, for example to use realloc on it, you don't need to pass its address. Just pass it as a int * as you do with pieces[i]:

void    top_left_helper(int *values, char *pieces)
{
    int i;
    int j;

    i = 0;
    j = 0;
    printf("value of values[0] = %d\n", values[0]);
    printf("value of values[0] = %d\n", values[1]);
    left_helper(values);    // probably need to change left_helper the same way
    top_helper(values);     // and also top_helper
    while (i < 16)
        pieces[i++] = '.';
    while (j < 4)
        pieces[values[j++]] = '#';
}

Then change the call accordingly:

top_left_helper(values, pieces[i]);

Upvotes: 2

Related Questions