Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
结构calloc中的动态数组或指针失败,C_C_Struct_Calloc - Fatal编程技术网

结构calloc中的动态数组或指针失败,C

结构calloc中的动态数组或指针失败,C,c,struct,calloc,C,Struct,Calloc,我试图在C中完成一个关于稀疏矩阵的赋值。我有一个稀疏矩阵,作为值和坐标的列表保存,并将其转换为耶鲁格式 我遇到了一个奇怪的内存分配问题,以前似乎没有人见过。我的代码是: yale* convertMatrix(matrix_list* input){ int matrix_elements = input->elements; int matrix_rows = input->m; yale* yale = (struct y*)calloc(1, sizeof(yale));

我试图在C中完成一个关于稀疏矩阵的赋值。我有一个稀疏矩阵,作为值和坐标的列表保存,并将其转换为耶鲁格式

我遇到了一个奇怪的内存分配问题,以前似乎没有人见过。我的代码是:

yale* convertMatrix(matrix_list* input){
int matrix_elements = input->elements;
int matrix_rows = input->m;

yale* yale = (struct y*)calloc(1, sizeof(yale));

int* A = (int*)calloc(matrix_elements, sizeof(int));
int* IA = (int*)calloc(matrix_rows + 1, sizeof(int));    
int* JA = (int*)calloc(matrix_elements, sizeof(int));

printf("%d elements\n",matrix_elements);

yale->A = A;      // Value
yale->IA = IA;          // Row (X)
yale->JA = JA;     // Column (Y)
yale->elements = matrix_elements;
yale->m = matrix_rows;
yale->n = input->n;

list* tmp_list = input->first;

for(int i = 0, j = 0, tmp_y = 0; i < matrix_elements && tmp_list!=NULL; i++){
    printf("Input Value: %d \n",tmp_list->point.value);
    A[i] = tmp_list->point.value;
    // Initialise the first row
    if(i == 0) IA[0] = tmp_list->point.x;
    else{
        // Add a new row index
        if(tmp_y != tmp_list->point.x){
            j++;
            IA[j] = i;
            tmp_y = tmp_list->point.x;
        }
    }
    JA[i] = tmp_list->point.y;
    tmp_list = tmp_list->next;
}

for(int i = 0; i < matrix_elements; i++)
    printf("%d,",yale->A[i]);
printf("\n");
for(int i = 0; i < matrix_rows + 1; i++)
    printf("%d,",yale->IA[i]);
printf("\n");
for(int i = 0; i < matrix_elements; i++)
    printf("%d,",yale->JA[i]);

return yale;
}
但是在循环的第一次迭代中,程序在第一个相关printf处出错

      printf("%d,",yale->A[i]);
我肯定: 在我的测试用例中,矩阵元素是一个整数9 矩阵_行是一个整数 A/IA/JA都用正确的值填充如果在printf中用A替换yale->A,效果很好。 直接调用数组到结构指针不会影响结果。 Mallocing,callocing,不是类型转换,都没有效果


多亏了Xcode和gdb,我还可以在SEGD故障点看到这一点。结构指针似乎没有指向数组

要编译它,我需要在代码段前面加上:

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

typedef struct y{
        int n;
        int m;
        int elements;
        int *IA;
        int *JA;
        int *A;
        } yale;

typedef struct list {
        struct list *next;
        struct point { int x,y,value; } point;
        } list;

typedef struct matrix_list {
        int elements;
        int m;
        int n;
        struct list *first;
        int *point;
        } matrix_list;
更新:我把程序转换成更可读的东西。我一点也不知道IA和JA应该做什么,但是下面的片段应该相当于OP

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

struct y {
        unsigned int n;
        unsigned int m;
        unsigned int elements;
        unsigned int *IA;
        unsigned int *JA;
        int *A;
        } ;

struct list {
        struct list *next;
        struct point { unsigned int x,y; int value; } point;
        } ;

struct matrix_list {
        unsigned int elements;
        unsigned int m;
        unsigned int n;
        struct list *first;
        } ;

struct y *convertMatrix(struct matrix_list* input)
{
unsigned int matrix_elements = input->elements;
unsigned int matrix_rows = input->m;
unsigned int ii,jj,tmp_y;

struct y *yale ;
struct list *tmp_list ;

yale = calloc(1, sizeof *yale);
assert (yale != NULL);

printf("%u elements\n",matrix_elements);

yale->A = calloc(matrix_elements, sizeof *yale->A);
assert (yale->A != NULL);
yale->IA = calloc(matrix_rows + 1, sizeof *yale->IA);
assert (yale->IA != NULL);
yale->JA = calloc(matrix_elements, sizeof *yale->JA);
assert (yale->JA != NULL);

yale->elements = matrix_elements;
yale->m = matrix_rows;
yale->n = input->n;

    // Initialise the first row, set start condition
        // FIXME: this ignores the empty list or size=0 cases
yale->IA[0] = tmp_y = input->first->point.x;
ii = jj = 0;
for(tmp_list = input->first ;tmp_list; tmp_list = tmp_list->next) {
    printf("Input Value: %d \n",tmp_list->point.value);
    yale->A[ii] = tmp_list->point.value;
        // Add a new row index
    if(tmp_y != tmp_list->point.x){
        jj++;
        yale->IA[jj] = ii;
        tmp_y = tmp_list->point.x;
    }
    yale->JA[ii] = tmp_list->point.y;
    if (++ii >= matrix_elements ) break;
}

for(int i = 0; i < matrix_elements; i++)
    printf("%d,",yale->A[i]);
printf("\n");
for(int i = 0; i < matrix_rows + 1; i++)
    printf("%u,",yale->IA[i]);
printf("\n");
for(int i = 0; i < matrix_elements; i++)
    printf("%u,",yale->JA[i]);

return yale;
}

注意:我将ii==0{}条件移出了循环,并用两个字母的等价物替换了一个字母的索引。另外:所有索引都是无符号的,因为它们应该是

我建议您在下面运行代码。这将报告缓冲区溢出错误。缓冲区溢出是指写入超过数组末尾的位置


我还建议您为代码编写一些单元测试。它们可以非常有助于检测bug。特别是,我建议您使用3x3输入矩阵编写一个测试,每个位置都有一个值。检查得到的值是否与预期值一致。

类型和变量名称相同不是一个好主意,因为这可能会在几周内给其他人或自己造成混淆。在第一个循环结束时打印i和j的值,为了确保您没有超过分配给A/IA/JA的内存的末尾,如果您发布了一个可编译的片段,这会有所帮助。另外:包括和删除类型转换。就我个人而言,我也会删除typedef,并将所有int替换为无符号int,但这是一个品味问题。我不知道这是否是最佳解决方案,但我通过调整convertMatrix将指向输出的指针作为输入,而不是返回输出,成功地解决了我的问题。我已经尽可能删除了不相关的函数
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

struct y {
        unsigned int n;
        unsigned int m;
        unsigned int elements;
        unsigned int *IA;
        unsigned int *JA;
        int *A;
        } ;

struct list {
        struct list *next;
        struct point { unsigned int x,y; int value; } point;
        } ;

struct matrix_list {
        unsigned int elements;
        unsigned int m;
        unsigned int n;
        struct list *first;
        } ;

struct y *convertMatrix(struct matrix_list* input)
{
unsigned int matrix_elements = input->elements;
unsigned int matrix_rows = input->m;
unsigned int ii,jj,tmp_y;

struct y *yale ;
struct list *tmp_list ;

yale = calloc(1, sizeof *yale);
assert (yale != NULL);

printf("%u elements\n",matrix_elements);

yale->A = calloc(matrix_elements, sizeof *yale->A);
assert (yale->A != NULL);
yale->IA = calloc(matrix_rows + 1, sizeof *yale->IA);
assert (yale->IA != NULL);
yale->JA = calloc(matrix_elements, sizeof *yale->JA);
assert (yale->JA != NULL);

yale->elements = matrix_elements;
yale->m = matrix_rows;
yale->n = input->n;

    // Initialise the first row, set start condition
        // FIXME: this ignores the empty list or size=0 cases
yale->IA[0] = tmp_y = input->first->point.x;
ii = jj = 0;
for(tmp_list = input->first ;tmp_list; tmp_list = tmp_list->next) {
    printf("Input Value: %d \n",tmp_list->point.value);
    yale->A[ii] = tmp_list->point.value;
        // Add a new row index
    if(tmp_y != tmp_list->point.x){
        jj++;
        yale->IA[jj] = ii;
        tmp_y = tmp_list->point.x;
    }
    yale->JA[ii] = tmp_list->point.y;
    if (++ii >= matrix_elements ) break;
}

for(int i = 0; i < matrix_elements; i++)
    printf("%d,",yale->A[i]);
printf("\n");
for(int i = 0; i < matrix_rows + 1; i++)
    printf("%u,",yale->IA[i]);
printf("\n");
for(int i = 0; i < matrix_elements; i++)
    printf("%u,",yale->JA[i]);

return yale;
}