在C中调整动态矩阵的大小

时间:2016-04-10 18:03:03

标签: c pointers malloc realloc

我遇到了一些非常愚蠢的麻烦。但我无法解决问题。我设计了一个函数,用于从动态调整大小的字符串构建列矩阵。

typedef struct{
double  ** m_;
size_t rows_, cols_;
}matrix_t;

int loadCol(char* str, matrix_t* col){
    size_t size=0; char* ptr;
    if(str==NULL)   return 0;
    if((col=(matrix_t*)malloc(sizeof(matrix_t)))==NULL) return 0;
    if((col->m_=(double**)malloc(sizeof(double*)))==NULL) return 0;
    ptr = strtok(str, "|");
    do{
        if(((col->m_)[0]=(double*)realloc((col->m_), sizeof(double)*(size+1)))==NULL){
            eraseMatrix(col); 
            return 0;
        }
        (col->m_)[0][size]=atof(ptr); /*SIGSEV*/
        size++;
    }while((ptr=strtok(NULL,"|"))!=NULL);
    col->cols_ = 1; col->rows_ = size;
    return size;
}

我使用gdb进行调试,问题似乎出现在带有注释SIGSEV的赋值行标记中。此外,当程序的流程从此功能范围中消失时,col-> cols_具有不正确的数据。 我的职能问题在哪里?

1 个答案:

答案 0 :(得分:1)

要在函数中修改col并将修改反映到调用者,需要将指向col的指针作为matrix_t **col传递。然后必须在函数中取消引用col 如果col声明为loadCol ( str, &col);

,则调用者将使用matrix_t *col = NULL;
int loadCol(char* str, matrix_t** col){
    size_t size=0; char* ptr;
    if(str==NULL)   return 0;
    if((*col=(matrix_t*)malloc(sizeof(matrix_t)))==NULL) return 0;
    if(((*col)->m_=(double**)malloc(sizeof(double*)))==NULL) return 0;
    ptr = strtok(str, "|");
    do{
        if((((*col)->m_)[0]=(double*)realloc(((*col)->m_)[0], sizeof(double)*(size+1)))==NULL){
            //eraseMatrix(col);
            return 0;
        }
        ((*col)->m_)[0][size]=atof(ptr);
        size++;
    }while((ptr=strtok(NULL,"|"))!=NULL);
    (*col)->cols_ = 1; (*col)->rows_ = size;
    return size;
}

strpbrk和strtod也可用于解析字符串中的值。

int loadCol(char* str, matrix_t** col){
    size_t size=0; char* ptr;
    char *next = NULL;
    if(str==NULL)   return 0;
    if((*col=(matrix_t*)malloc(sizeof(matrix_t)))==NULL) return 0;
    if(((*col)->m_=(double**)malloc(sizeof(double*)))==NULL) return 0;
    next = str;
    while((ptr=strpbrk(next,"0123456789-+."))!=NULL) {
        if((((*col)->m_)[0]=(double*)realloc(((*col)->m_)[0], sizeof(double)*(size+1)))==NULL){
            //eraseMatrix(col);
            return 0;
        }
        ((*col)->m_)[0][size]=strtod(ptr,&next);
        size++;
    }
    (*col)->cols_ = 1; (*col)->rows_ = size;
    return size;
}