C中的指针 - 构造矩阵时的“分割错误”

时间:2012-04-22 13:03:00

标签: c matrix struct segmentation-fault

我在32位Ubuntu虚拟机上使用Eclipse来处理项目。在尝试实现结构时或者在尝试运行特定函数时,我遇到了一个大问题。功能就是这个:

int count (matrix m, int v[], int w[], int col) {

    int r=0;
    int j=0;

    while (j < m.length) {
        int k=0;
        bool aux=true;

        while (k < col && aux ){
            if (v[k] == 1) {
                if(m.i[j][k] != w[k])
                    aux=false;
            }
            k++;
        }

        if(aux) r++;
        j++;
    }
    return r;
}

此函数接收一个矩阵(在下面定义),一个带有1和0的向量(用于了解要搜索的列,带有我们要在这些列中搜索的值的向量以及列数(等于长度)当它击中第二个“如果”它给我分段错误(我无法理解它是什么)时,我可以看到以这种方式定义它是不正确的,但我已经尝试过并试过了我似乎无法找到一种方法来访问向量中的值。这是我的结构矩阵:

typedef int *ind; 

struct matrix { 
    ind *i;
    int length;
};
typedef struct matrix matrix;

在这个结构中,我的矩阵有一个指针和长度(行数);指针指向一个指针向量(每行一个指针),这些指针中的每一个指向一个矢量,实际上是我的矩阵行。这里我的函数添加并创建一个空矩阵:

matrix emptyS(int n, int col) {
matrix m;
int d=0;
m.length=0;
m.i=(ind*) malloc(sizeof(int)*n);
int x;
    for (x=0; x < n; x++)
           {
               *m.i = (int*) malloc(sizeof(int)*col);
           }
while (d<n){
    m.i[d]=NULL;
    d++;
}
return m;
} /*Updated*/

matrix add(matrix m,int v[]){
    m.i[m.length+1]=v;
    m.length++;
    return m;
}

我知道这是一个非常具体的问题,但我一直在疯狂改变我的功能,似乎无法取得成功。

3 个答案:

答案 0 :(得分:5)

您对i的定义是:

 ind *i;

您对ind的定义如下:

typedef int* ind;

这意味着您对i的定义确实如此:

int ** i;

这是指向指针的指针,这意味着您必须错误地分配内存。

m.i=(ind*) malloc(sizeof(int)*n); 

此分配仅适用于int*,但第二个指针呢?你从来没有为它分配任何记忆!

分配矩阵的行,如下所示:

for (int x = 0; x < nofrows; x++)
   { 
       *m.i = (int*)malloc(sizeof(int)); 
   }

修改

为矩阵分配后的代码,将矩阵中的指针设置为NULL,基本上保留刚刚分配的所有内存悬空没有任何指向它 !!

while (d<n){
    m.i[d]=NULL; <--- LEAVES YOUR MEMORY JUST ALLOCATED FOR ROW d DANGLING.
    d++;
}

你不应该把它设置为NULL,而应该在你刚刚为你分配内存的矩阵中写东西。

答案 1 :(得分:1)

替换

m.i=(ind*) malloc(sizeof(int)*n);

通过

m.i=(ind*) malloc(sizeof(ind)*n);

我希望这会有所帮助。

答案 2 :(得分:1)

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

typedef enum{false,true}  bool;

typedef struct matrix_ {
    int **rows;
    unsigned size ;
    unsigned used ;
} matrix;

unsigned count (matrix m, int v[], int w[], unsigned ncol) {
    unsigned cnt=0;
    unsigned j=0;

    for (j=0; j < m.used; j++) {
        unsigned k;
        bool aux=true;

        for (k=0;k < ncol && aux; k++ ){
            if (v[k] == 1  && m.rows[j][k] != w[k]) {
                    aux=false;
            }
        }

        if(aux) cnt++;
    }
    return cnt;
}
#define barf(s) do { \
    fprintf (stderr, "%s\n", s); \
    exit (EXIT_FAILURE); \
    } while(0)

matrix emptyS(unsigned siz) {
    matrix m;
    unsigned d;

    m.used=0;
    m.size = siz;
    m.rows = malloc(siz * sizeof *m.rows );

    for (d=0; d<siz; d++){
        m.rows[d]=NULL;
    }
    return m;
}

matrix add(matrix m,int v[]){
    if (m.used >= m.size) barf("Danger, Bill Robinson!" );
    m.rows[m.used++]=v;
    return m;
}
int main(void)
{
int a[] = { 0,1,0};
int b[] = { 0,1,1};
int c[] = { 0,0,0};
int v[] = { 1,0,1};
int w[] = { 0,1,0};
matrix mymatrix;
unsigned zcount;

mymatrix = emptyS(3);
mymatrix = add( mymatrix, a);
mymatrix = add( mymatrix, b);
mymatrix = add( mymatrix, c);

zcount = count(mymatrix, v, w, 3);

printf("Count = %u\n", zcount);

return 0;
}

一些&#39;风格&#39;提示:

  • for循环比while()循环更不容易出错,并保存两行。
  • 对于计数和索引,无符号类型不易出错。 (只有一个角落案例)
  • 不要在typedef中隐藏指针;它会让你自己和别人感到困惑。
  • 不要施放malloc()的返回值;它不是必需的,可能会抑制错误消息。
  • ptr = malloc (n * sizeof *ptr)是更稳定的WRT拼写错误以及未来的修改。
  • 如果您分配一个可变尺寸的对象(例如您的矩阵),则存储该对象的大小(元素数量) 。对象应该是&#34;自包含的&#34;。