Почему мой массив содержит значения мусора / segfaulting после передачи его в другую функцию? - PullRequest
2 голосов
/ 03 апреля 2019

У меня есть функция, которая размещает массив для хранения значения для кодирования. После того, как значения закодированы в массив целых чисел, сам этот массив передается по ссылке (по крайней мере, это теория). Тем не менее, я получал значения мусора, когда компилировал функцию, поэтому я начал бросать операторы печати везде, чтобы увидеть, что происходит. Сразу после вызова второй функции и передачи массива я понимаю, что операторы печати являются ошибками, что странно для меня.

Основная функция:

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++;
    }
}

Однако, после того, как она передана в эту функцию:

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++]] = '#';
}

Это вызывает ошибку во втором операторе печати. Я действительно не вижу объяснения этому, кроме моего недопонимания, как работает передача параметров по ссылке и памяти. Пожалуйста, пролите немного света.

EDIT: После некоторого тестирования кажется, что если я распечатаю значения путем увеличения указателя вместо доступа к массиву, я могу правильно получить доступ к значениям для печати. Но это все еще не имеет смысла, почему доступ к массиву не будет работать. (следующие строки были добавлены во второй функции)

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);

1 Ответ

2 голосов
/ 03 апреля 2019

Это не делает то, что вы думаете:

*values[1]

[] имеет более высокий приоритет, чем *, поэтому этот индекс сначала индексирует values как массив, а затем разыменовывает значение, которое он возвращает. Но то, что вы передали в эту функцию, это указатель на переменную, которая также является указателем. Так что values[1] не имеет смысла. Вам сходит с рук *values[0], потому что это то же самое, что и **values То, что вы хотите:

(*values)[1]

Однако, если вам не нужно изменить vaules, например, для использования realloc, вам не нужно передавать его адрес. Просто передайте его как int *, как вы делаете с 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++]] = '#';
}

Затем измените вызов соответственно:

top_left_helper(values, pieces[i]);
...