C语言矩阵,分配内存时不会将所有元素清零?

3
我正在尝试编写一个小型矩阵程序。使用双指针不起作用,所以我想最简单的方法是有一个结构体,它有#行和#列以及一个一维数组作为矩阵。
但是在矩阵的初始化中出现了一些错误,因为我得到了(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。


谢谢大家,现在它可以工作了。但是malloc+memset和calloc之间的效率有什么区别吗?还是calloc只是malloc+memset的简单组合? - user1190832
6个回答

7

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

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

或者您可以使用memset显式地将这些位设置为零。


谢谢大家,现在可以工作了。但是malloc+memset和calloc之间是否有效率差异?还是说calloc就是简单的malloc+memset? - user1190832
为什么malloc + memset比calloc慢? - LihO

2
< p > malloc分配的对象具有未指定的值。如果需要,您必须自行将对象清零(例如使用memset函数),或者调用calloc而不是malloc。< /p >

1

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

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

使用

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

回答您的后续问题:

然而,malloc+memset和calloc之间是否有效率上的差异?或者说,calloc只是malloc+memset吗?

通常情况下,对于“小”的分配,calloc等同于malloc+memset。对于“大”的分配(多个页面,至少),您的库可能会依赖一些操作系统支持来做出更聪明的处理。其中一种方法是让操作系统在实际使用分配的页面时懒惰地零填充它们,而不是在分配时立即填充所有页面。


1

malloc()不能保证内存清零。使用calloc()来分配带有零的内存。


1

malloc不会初始化为0(因为性能问题...这并不总是你想要的)...

使用 calloc() 代替。


0

没错。C规范并没有说明数组被初始化为任何值。你只是得到一块内存,里面有之前的任何值。

不过你可以很容易地初始化为零:memset(mtrx->m, 0, sizeof(int) * r * c);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接