C矩阵,分配不是所有元素都是零?

时间:2012-02-05 16:19:55

标签: c memory-management matrix initialization malloc

我正在尝试编写一个小矩阵程序。使用双重指针不起作用所以我认为最简单的方法是使用#rows和#columns以及1d数组作为矩阵的结构。

但是我得到的矩阵启动有一些错误: 索引(0,0)和(0.1)的奇怪值而不是0。

这可能与此有关: matrix * mtrx = malloc(sizeof(matrix)); mtrx-> m = malloc(r * c * sizeof(int));

matrix.c:

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

matrix *alloc_matrix(int r, int c)
{
 matrix *mtrx = malloc(sizeof(matrix));
 mtrx->m = malloc(r * c * sizeof(int));
 if (mtrx == NULL || m == NULL) {
   printf("Out of memory.");
   exit(1);
 }
 mtrx->rows = r;
 mtrx->columns = c;
 return mtrx;
}

void free_matrix(matrix *mtrx)
{
 free(mtrx->m);
 free(mtrx);
}

void set(matrix *mtrx, int r, int c, int v)
{
 (mtrx->m)[r * mtrx->columns + c] = v;
}

int get(matrix *mtrx, int r, int c)
{
 return (mtrx->m)[r * mtrx->columns + c];
}

void print_matrix(matrix *mtrx)
{
 int i,j;
 printf("\n");
 for(i=0; i<mtrx->rows; i++) {
   for(j=0; j<mtrx->columns; j++) {
     printf("%i ", get(mtrx,i,j));
   }
   printf("\n");
 }
}

matrix.h:

struct matrix_ {
 int rows;
 int columns;
 int *m;
};
typedef struct matrix_ matrix;

matrix *alloc_matrix(int r, int c);
void free_matrix(matrix *mtrx);
void set(matrix *mtrx, int r, int c, int v);
int get(matrix *mtrx, int r, int c);
void print_matrix(matrix *m);

main.c中:

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

int main(void)
{
 matrix *m = alloc_matrix(3,4);
 print_matrix(m);
 printf("\nm[0][0] = %i", get(m,0,0));
 set(m,0,0,0);
 printf("\nm[0][0] = %i", (m->m)[0]);
  printf("\nm[0][0] = %i", (m->m)[12]);

 return 0;
}

输出: 除(0,0)和(0,1)之外的所有元素都是0。

6 个答案:

答案 0 :(得分:7)

函数malloc分配一块内存,返回指向块开头的指针。它没有将所有位设置为零。

分配一块内存并将其所有位初始化为零 - 这是calloc函数的用途。

或者您可以使用memset

将这些位显式设置为零

答案 1 :(得分:2)

malloc分配的对象具有未指定的值。如果需要,您必须自己将对象置零(例如使用memset函数)或调用calloc而不是malloc

答案 2 :(得分:1)

malloc不会将已分配的内存清零。如果要在分配时使用零填充矩阵,请改用calloc。在您的情况下,请替换:

mtrx->m = malloc(r * c * sizeof(int));

mtrx->m = calloc(r*c, sizeof(int));

回答你的后续问题:

  

但是malloc + memset和calloc之间的效率是否存在差异?或者是calloc simplee malloc + memset?

通常,对于“小”分配calloc相当于malloc + memset。对于“大”分配(至少多个页面),您的库可能会依赖一些OS支持来做更聪明的事情。一种方法是操作系统在实际使用时懒得零填充分配的页面,而不是在分配后立即填写所有页面。

答案 3 :(得分:1)

malloc()不保证将内存归零。使用calloc()用零分配内存。

答案 4 :(得分:1)

malloc不会以0开头(因为性能问题......它并不总是你想要的)......

使用 calloc ()代替。

答案 5 :(得分:0)

这是正确的。 C规范并没有说数组是针对任何东西启动的。你只需得到一块内存就可以获得之前的任何值。

您可以轻松初始化为sero:memset(mtrx->m, 0, sizeof(int) * r * c);