C объяснение обозначения указателя? - PullRequest
0 голосов
/ 09 октября 2018

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

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

struct foo {
    int size;
    int *array;
};

typedef struct foo bar;

bar* readArray(){
    bar *fbar = (bar *)malloc(sizeof(bar));
    fbar->array = (int *)malloc(sizeof(int)*2); //ADDED THIS LINE FOR TESTING
    int i = 0;
    int temp;
    while(scanf("%d", &temp) == 1){
        *(fbar->array + (i-1)) = temp; //THIS LINE HERE
        i++;
    }
    if(i == 0){
        printf("No numbers were entered!");
    }
    fbar->size = i;
    return fbar;

}

int main(){
    bar *p = readArray();
    return 0;
}

Я попытался запустить ее, что, конечно, вызывает segfault, потому что в примере не было mallocпространство для * массива.Я попытался протестировать строку, используя неправильное пространство для 2-х int, чтобы проверить, сработали ли первые 2 цикла.Я предполагал, что программа получит segfault после того, как будут прочитаны первые 2 int, что не произошло (программа продолжает работать).Теперь я не понимаю, что делает эта строка кода и почему я не segfaulting.

Я не могу точно выяснить, что является ошибкой, или если есть даже ошибка помимо отсутствия malloc () для массива int *.

1 Ответ

0 голосов
/ 09 октября 2018

Для любого указателя (или массива) p и индекса i выражение *(p + i) точно равно p[i].

Теперь, если мы возьмем ваше выражение *(fbar->array + (i-1)), с приведенным вышеэто равно fbar->array[i - 1].

Проблема должна быть ясна, что происходит, когда i == 0 и у вас fbar->array[-1].Это выходит за пределы и приведет к неопределенному поведению .

Что касается того, почему он не падает, это часть неопределенного поведения .Это может привести к сбою, может показаться, что оно работает (как и для вас), или оно может вызвать носовых демонов .

...