这些代码行怎么会导致完全相同的程序有时崩溃但其他程序运行良好?

How could these lines of code cause the exact same program to crash sometimes but work fine others?

我有一个带有 int 的结构和一个指向结构的指针数组:

//Define a struct
struct city
{
    //Declaration of struct members
    int city_num;
    struct city **connected;
};

和这些结构的 'n' 数组:

struct city* cities;
cities = malloc(n*sizeof(struct city));

我想在为另一个结构分配 space 后,将指向一个结构的指针分配给另一个结构的 'connected' 成员。

cities[j].connected = realloc(cities[j].connected, (1*sizeof(struct city*));
cities[i].connected = realloc(cities[i].connected, (1*sizeof(struct city*));

cities[j].connected[0]=&list[i];
cities[i].connected[0]=&list[j];

但程序有时会在最后两行崩溃。昨天它像现在一样崩溃,然后在深夜它开始像那样工作而我没有改变任何东西(我只是评论其余的代码)今天在工作了一上午之后它刚刚决定再次开始崩溃. (我正在使用 Code::Blocks 13.12)

我整理了一个非常简化的程序版本来向大家展示问题所在。

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

//Define a struct
struct city
{
    //Declaration of struct members
    int city_num;
    struct city **connected;
};

int main()
{
    int n = 2;
    struct city* cities;

    cities = malloc(n*sizeof(struct city));

    cities[0].city_num = 1;
    cities[1].city_num = 2;

    cities[0].connected = realloc(cities[0].connected, (1*sizeof(struct city*)));
    cities[1].connected = realloc(cities[1].connected, (1*sizeof(struct city*)));

    //CRASHES AT THESE TWO LINES <-------------------------------------------------
    cities[0].connected[0]=&cities[1];
    cities[1].connected[0]=&cities[0];

    //I have ommitted the memory freeing from this code as the problem is caused above this point

    return 0;
}

realloc() 的第一个参数必须是 malloc() 返回的地址,或者是先前对 realloc().

的调用

下一行:

cities[0].connected = realloc(cities[0].connected, (1*sizeof(struct city*)));

通过 cities[0].connected,其中不包含这些函数之一返回的地址。事实上,它根本没有被初始化!因此,这是对 realloc().

的无效调用

这被认为是未定义的行为,并且可能会使您的代码崩溃。但是,由于我们不知道您传递的地址是什么,而且每次都可能是不同的地址,因此有时可能不会崩溃。但是总是错的。

注意:如果您将 NULL 作为第一个参数传递,那么 realloc() 将像 malloc() 一样工作。但是这里你传递的是一个单位化的值,它可以是任何东西。

你需要做这样的事情:

cities[0].connected = malloc(1*sizeof(struct city*));

请注意,释放此内存的代码变得有点复杂,因为您需要释放这些地址中的每一个。

realloc() 在需要的内存比以前由 malloc()calloc() 分配的内存多时重新分配内存。

但是当传递的第一个参数是NULL时它也有效。

所以回答你的问题你的代码有时有效有时无效的原因是因为虽然传递的指针没有被先前的分配初始化,它发生有时NULL