尝试在C中打印结构数组

尝试在C中打印结构数组,c,arrays,struct,printing,C,Arrays,Struct,Printing,我被要求构建一个函数,它接收一个包含大量零的静态二维数组,并将其转换为一个结构数组。每个结构包含非零的值和列的索引。 现在我已经构建了它,但问题在于打印功能 1) 当我尝试打印两次时,它只打印一次,第二次列表变为空。为什么会发生这种情况 print(list); print(list); 2) 为什么我不能像在主函数中那样打印 printf("this is just a print |%d||%d| ", list[0]->next->next->n

我被要求构建一个函数,它接收一个包含大量零的静态二维数组,并将其转换为一个结构数组。每个结构包含非零的值和列的索引。

现在我已经构建了它,但问题在于打印功能

1) 当我尝试打印两次时,它只打印一次,第二次列表变为空。为什么会发生这种情况

    print(list);  
    print(list);
2) 为什么我不能像在主函数中那样打印

printf("this is just a print |%d||%d|  ", list[0]->next->next->next->data, list[0]->col);
为什么我不能访问它,程序崩溃了

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//#include <vld.h>
#include <string.h>
#include <ctype.h>
#define C 5
#define N 4

typedef struct Node {
    int data;
    int col;
    struct Node *next;
} node;

node **fun(int arr[N][C]) { 
    int i, j, k;
    node **list;
    node *temp;

    list = (node**)calloc(N, sizeof(node *));

    for (i = 0; i < N; i++) {
        list[i] = NULL;
        for (j = C - 1; j >= 0; j--)
            if (arr[i][j] != 0) {
                temp = (node*)malloc(sizeof(node));
                temp->data = arr[i][j];
                temp->col = j;
                temp->next = list[i];
                list[i] = temp;
            }
    }
    return list;
}

void print(node **head) {
    int i;
    node **temp = head;
    for (i = 0; i < N; i++) {
        while (temp[i]) {
            printf("|%d||%d|  ", temp[i]->data, temp[i]->col);
            temp[i] = temp[i]->next;
        }
        printf("\n\n");
    }
}

void main() {
    int arr[N][C] = { {0,0,4,0,7}, {3,0,0,0,0}, {9,1,0,6,0} , {0,0,0,0,0} };
    node **list;
    list = fun(arr);

    print(list);  ///////////
    print(list);  ///////////////

    printf("this is just a print |%d||%d|  ", list[0]->next->next->next->data, list[0]->col);
}
#包括
#包括
#包括
//#包括
#包括
#包括
#定义C5
#定义n4
类型定义结构节点{
int数据;
int col;
结构节点*下一步;
}节点;
节点**fun(int arr[N][C]){
int i,j,k;
节点**列表;
节点*温度;
list=(node**)calloc(N,sizeof(node*);
对于(i=0;i=0;j--)
如果(arr[i][j]!=0){
temp=(node*)malloc(sizeof(node));
温度->数据=arr[i][j];
温度->柱=j;
临时->下一步=列表[i];
列表[i]=临时;
}
}
退货清单;
}
无效打印(节点**头){
int i;
节点**温度=头部;
对于(i=0;idata,temp[i]->col);
温度[i]=温度[i]->下一步;
}
printf(“\n\n”);
}
}
void main(){
int arr[N][C]={0,0,4,0,7},{3,0,0,0,0},{9,1,0,6,0},{0,0,0,0};
节点**列表;
列表=乐趣(arr);
打印(列表)///////////
打印(列表)///////////////
printf(“这只是一个打印|%d | |%d |”,list[0]->next->next->next->data,list[0]->col);
}

如评论中所述,在打印指针列表的过程中,您正在销毁指针列表:

    while(temp[i])
    {   printf("|%d||%d|  ",temp[i]->data,temp[i]->col);
        temp[i]=temp[i]->next;    // <---- here
    }

如评论中所述,在打印指针列表的过程中,您正在销毁指针列表:

    while(temp[i])
    {   printf("|%d||%d|  ",temp[i]->data,temp[i]->col);
        temp[i]=temp[i]->next;    // <---- here
    }

您的
print
函数修改数组:它使用数组元素在列表中迭代,并将其保留为
NULL

以下是更正的版本:

void print(node **head) {
    int i;
    for (i = 0; i < N; i++) {
        node *temp;
        for (temp = head[i]; temp; temp = temp->next) {
            printf("|%d||%d|  ", temp->data, temp->col);
        }
        printf("\n\n");
    }
}
无效打印(节点**头){
int i;
对于(i=0;i下一步){
printf(“|%d |%d |”,temp->data,temp->col);
}
printf(“\n\n”);
}
}

您的
print
函数修改数组:它使用数组元素遍历列表,并将其保留为
NULL

以下是更正的版本:

void print(node **head) {
    int i;
    for (i = 0; i < N; i++) {
        node *temp;
        for (temp = head[i]; temp; temp = temp->next) {
            printf("|%d||%d|  ", temp->data, temp->col);
        }
        printf("\n\n");
    }
}
无效打印(节点**头){
int i;
对于(i=0;i下一步){
printf(“|%d |%d |”,temp->data,temp->col);
}
printf(“\n\n”);
}
}

关于second项-您可能在某个时候访问空的“next”,使其崩溃。。。如果你在linux上,试着用gdb去bug…
temp[i]=temp[i]->next破坏性地改变了列表的结构。而且,很明显,你的下一个节点指向它自己,而不是下一个节点。。。不确定我是否能理解您的代码,但显然这是在填充节点时发生的…关于second项-您可能在某个点访问空“next”,使其崩溃。。。如果你在linux上,试着用gdb去bug…
temp[i]=temp[i]->next破坏性地改变了列表的结构。而且,很明显,你的下一个节点指向它自己,而不是下一个节点。。。不确定我是否能理解你的代码,但显然这是在节点被填充时发生的…感谢你的修复工作,Ohhhhh,所以我使用Temp[I]运行,并将其设置为Null。。。我明白了,非常感谢你的修复工作,所以我用Temp[I]运行并使其为空。。。我明白了,非常感谢much@EddieKnaz:סלח,为了与C99之前的编译器兼容,我修改了答案。你应该得到一个更现代的编译器,你使用什么环境?哦,在2017年对它运行,对不起,但我使用2010年;s对于我们只使用2010的学校,Visual Studio 2010在C99标准采用10年后问世,但仍然没有实施其大部分改进。微软游说委员会让它的安全API进入,但不想实现大多数更有用的扩展。他们又花了5年时间才最终入伙。这里有一个详细的解释:@EddieKnaz:סלח,我修改了答案以与C99之前的编译器兼容。你应该得到一个更现代的编译器,你使用什么环境?哦,在2017年对它运行,对不起,但我使用2010年;s对于我们只使用2010的学校,Visual Studio 2010在C99标准采用10年后问世,但仍然没有实施其大部分改进。微软游说委员会让它的安全API进入,但不想实现大多数更有用的扩展。他们又花了5年时间才最终入伙。以下是详细说明: