user-0 提问: 【求助】结构体变量不用malloc分配空间初始化，在函数里就没法运行

回复:
user: user-0
content: 引用 6 楼 jianwen0529 的回复:[quote=引用 5 楼 trueJIMO 的回复:] 膜拜大佬..真的是如你所说... 但为什么我上面另一种写法用malloc分配过后就没有问题 还有就是“指向二维数组的指针，那么取值是三维写法”这句话该怎么理解啊。为什么从二维数组变成了三维数组... 我猜是：malloc是在堆上分配内存，越界修改其他内存导致崩溃的概率也许比在栈上的概率更小。 以上说法并没有什么根本，总而言之不管如何，这个越界读写都是一种错误的写法（除非是作者是明确在某些情况下进行）  指向二维数组的指针：因为这个近似于三级指针（近似而不是等价）[/quote] 明白了，谢大神

user: user-1
content: 引用 5 楼 trueJIMO 的回复:膜拜大佬..真的是如你所说... 但为什么我上面另一种写法用malloc分配过后就没有问题 还有就是“指向二维数组的指针，那么取值是三维写法”这句话该怎么理解啊。为什么从二维数组变成了三维数组... 我猜是：malloc是在堆上分配内存，越界修改其他内存导致崩溃的概率也许比在栈上的概率更小。 以上说法并没有什么根本，总而言之不管如何，这个越界读写都是一种错误的写法（除非是作者是明确在某些情况下进行）  指向二维数组的指针：因为这个近似于三级指针（近似而不是等价）

user: user-1
content: (*D)[v][w].vrtype.adj = 6; // *D 才是那个数组，否则应该写成D[0][v][w]，指向二维数组的指针，那么取值是三维写法  或者直接这样子 void ShortestPath_FLOYD(DistanceMatrix D)

user: user-0
content: 引用 1 楼 jianwen0529 的回复:(*D)[v][w].vrtype.adj = 6; // *D 才是那个数组，否则应该写成D[0][v][w]，指向二维数组的指针，那么取值是三维写法  或者直接这样子 void ShortestPath_FLOYD(DistanceMatrix D) 我写的是D[v][w]->vrtype.adj=6这跟(*D)[v][w].vrtype.adj = 6是等效的啊，程序编译能通过运行的时候出现错误

user: user-0
content: 引用 4 楼 jianwen0529 的回复:[quote=引用 3 楼 trueJIMO 的回复:] [quote=引用 1 楼 jianwen0529 的回复:] (*D)[v][w].vrtype.adj = 6; // *D 才是那个数组，否则应该写成D[0][v][w]，指向二维数组的指针，那么取值是三维写法  或者直接这样子 void ShortestPath_FLOYD(DistanceMatrix D) 我写的是D[v][w]->vrtype.adj=6这跟(*D)[v][w].vrtype.adj = 6是等效的啊，程序编译能通过运行的时候出现错误[/quote]  当然是不等效的，编译没问题只是说明语法没错。但是运行的时候越界了，是否运行正确以及能否正常运行这都是不可预料的 如同 int (*p)[3]; p[1]-> // p[0]地址是指向一个大小为3的一个数组，而p[1]是指向之后的下一个大小为3的一个数组 p[0][1]. 是不一样的   #include <stdio.h>  #define MAX_VERTEX_NUM 20  typedef struct{     int adj; }VRType;  typedef struct{ }InfoType;  typedef struct ArcCell{     VRType vrtype;     InfoType *info; }ArcCell, DistanceMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  // D的类型是 ArcCell (*)[MAX_VERTEX_NUM][MAX_VERTEX_NUM]  void ShortestPath_FLOYD(DistanceMatrix *D){     for (int v = 0; v < 3; ++v)     {         for (int w = 0; w < 3; ++w){             printf("%p\n", D[v][w]); // v一个步长的大小是 sizeof(ArcCell)*MAX_VERTEX_NUM*MAX_VERTEX_NUM             printf("%p\n", &D[v][w][0]); //上面等价于这个语句             printf("%p\n", &D[0][v][w]);             printf("\n");         }     } }  DistanceMatrix D; int main() {     ShortestPath_FLOYD(&D);     return 0; }[/quote] 膜拜大佬..真的是如你所说... 但为什么我上面另一种写法用malloc分配过后就没有问题 还有就是“指向二维数组的指针，那么取值是三维写法”这句话该怎么理解啊。为什么从二维数组变成了三维数组...

user: user-2
content: 代码没有问题，D是一个数组的数组类型， 大小已定，无需重新分配内存。

user: user-1
content: 引用 3 楼 trueJIMO 的回复:[quote=引用 1 楼 jianwen0529 的回复:] (*D)[v][w].vrtype.adj = 6; // *D 才是那个数组，否则应该写成D[0][v][w]，指向二维数组的指针，那么取值是三维写法  或者直接这样子 void ShortestPath_FLOYD(DistanceMatrix D) 我写的是D[v][w]->vrtype.adj=6这跟(*D)[v][w].vrtype.adj = 6是等效的啊，程序编译能通过运行的时候出现错误[/quote]  当然是不等效的，编译没问题只是说明语法没错。但是运行的时候越界了，是否运行正确以及能否正常运行这都是不可预料的 如同 int (*p)[3]; p[1]-> // p[0]地址是指向一个大小为3的一个数组，而p[1]是指向之后的下一个大小为3的一个数组 p[0][1]. 是不一样的   #include <stdio.h>  #define MAX_VERTEX_NUM 20  typedef struct{     int adj; }VRType;  typedef struct{ }InfoType;  typedef struct ArcCell{     VRType vrtype;     InfoType *info; }ArcCell, DistanceMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  // D的类型是 ArcCell (*)[MAX_VERTEX_NUM][MAX_VERTEX_NUM]  void ShortestPath_FLOYD(DistanceMatrix *D){     for (int v = 0; v < 3; ++v)     {         for (int w = 0; w < 3; ++w){             printf("%p\n", D[v][w]); // v一个步长的大小是 sizeof(ArcCell)*MAX_VERTEX_NUM*MAX_VERTEX_NUM             printf("%p\n", &D[v][w][0]); //上面等价于这个语句             printf("%p\n", &D[0][v][w]);             printf("\n");         }     } }  DistanceMatrix D; int main() {     ShortestPath_FLOYD(&D);     return 0; }