变量变化的位置?

时间:2018-11-09 20:26:33

标签: c segmentation-fault c99

我有一些代码,但是由于某种原因,变量的位置在我的代码中间发生了变化。 我主要从stdin读取一个整数,然后malloc分配一个结构数组。

int main(){
    int numcities;
    scanf("%d", &numcities);

    City **cities = malloc(numcities*sizeof(City)*2); //*2 is just to be sure, gonna remove that later.

    for(int n = 0;n<numcities;n++){
        int nularr[numcities];
        for(int n2 = 0;n2<numcities;n2++){
            nularr[n2] = 0;
        }
        City c = {
            .value = 1,
            .options = nularr,
        };
        cities[n] = &c;
    };

    readRoads(cities, numcities);
}

readRoads如下所示。在调用readRoads之前,我可以访问numcities(gdb和代码内部),但是在尝试使用它时会出现sigsegvs,并且在gdb中抱怨无法读取0xffffffcd的内存。 如果我使用了一个指向麻木的指针并在以后取消引用,那么一切都将保持完整。但是在调用readRoads之后获取指针会给我0xffffffcd(一致),这是不可读的。 我已经从malloc收到了两倍于必要的内存,

void readRoads(City **cities, int N){
    for(int n = 0;n<N;n++){
        int buf;
        int res[N];
        int roads = 0;
        City *options[N];
        scanf("%d", &buf);
        for(int r = 0;r<N;r++){
            res[r]= buf << r;
            if(res[r]){
                options[roads] = cities[r];
                roads++;
            }
        }

        cities[n]->id = n;
        cities[n]->name = n +'A';
        cities[n]->optionsCount = 1;

        for(int i = 0; i < roads; i++){
            cities[n]->options[i] = options[i]->id;
        }
    }
}

2 个答案:

答案 0 :(得分:3)

当您分配给cities数组时:

for(int n = 0;n<numcities;n++){
    int nularr[numcities];
    for(int n2 = 0;n2<numcities;n2++){
        nularr[n2] = 0;
    }
    City c = {
        .value = 1,
        .options = nularr,
    };
    cities[n] = &c;
};

您正在分配局部变量的地址。该变量在for循环的末尾超出范围,因此最终指向无效的内存。取消引用此无效指针将调用undefined behaivor。当您将nularr分配给这些实例之一时,会发生同样的事情

仅创建City数组,而不是创建指向City的指针数组。另外,您需要动态分配nularr

City *cities = malloc(numcities*sizeof(City));

for(int n = 0;n<numcities;n++){
    int *nularr = calloc(numcities, sizeof(int);
    cities[n].value = 1;
    cities[n].options = nularr;
};

也相应地更改readRoads

void readRoads(City *cities, int N){
    ...

并确保检查malloc / calloc的返回值是否有错误。

答案 1 :(得分:0)

    City c = {
        .value = 1,
        .options = nularr,
    };
    cities[n] = &c;
}

在此}c超出范围并停止存在(这是该块中的局部变量)。

您刚刚保存的指针(cities[n])不确定。

基本上,城市现在是无效指针的数组。


(此外,应将其初始化为

City **cities = malloc(numcities * sizeof (City *));

具体来说,sizeof (City *),而不是sizeof (City)。)