问题描述
试图了解C中双指针的用法和内存分配。
下面是我的代码:-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
printf("Enter rows and columns respectively: -\n");
int rows,columns;
scanf("%d%d",&rows,&columns);
int **matrix;
matrix = calloc(rows,sizeof(int));
int i,j;
for(i = 0; i < rows; i++)
{
matrix[i] = calloc(columns,sizeof(int));
}
printf("Enter your elements\n");
for(i = 0; i < rows; i++)
{
for(j = 0; j < columns; j++)
{
scanf("%d",&matrix[i][j]);
}
}
printf("Your elements are: -\n");
for(i = 0; i < rows; i++)
{
for(j = 0; j < columns; j++)
{
printf("%d ",matrix[i][j]);
}
printf("\n");
}
free(matrix);
return 0;
}
获得Segmentation fault: 11
之后,我在网上搜索了一下,发现没有写这个:-
int **matrix;
matrix = calloc(rows,sizeof(int));
我应该写:-
int **matrix;
matrix = calloc(rows,sizeof(int*));
进行上述更改后,我的代码可以正常工作。
我的问题是:-
- sizeof(int)和sizeof(int *)有什么区别?
- 他们俩都不分配4个字节吗? (int占用4个字节,int占用* (除了指针,还需要注意)还占用4个字节?
- 如果两个人都分配了相同的空间,那为什么我得到一个 第一种情况下的细分错误?
解决方法
他们俩都不分配4个字节吗? (int占用4个字节,而int *(虽然是一个指针)也占用4个字节?
是什么使您认为指针是四个字节?在大多数现代(64位)架构上,指向对象的指针是8个字节,而不是4个字节。
因此,通常为sizeof(int) ≠ sizeof(int *)
。但是您不能对可移植C代码中的对象大小做很多假设,并且绝对不能假设sizeof(int) == 4
或sizeof(int*) == 8
(也不能4
)。根据平台,这些大小会有所不同。它们可以也具有相同的大小。您只是不能假设这一点。
为避免指针和指针的大小混淆,某些人(包括我)建议在分配sizeof
表达式中使用对象名称,而不要使用类型名称:
int **matrix = calloc(rows,sizeof *matrix);
// …
matrix[i] = calloc(columns,sizeof **matrix);
这可以清楚地说明您要分配的内容。请注意,sizeof expr
不会评估 expr
;这很重要,因为在分配内存之前,表达式*matrix
和**matrix
是无效 -延迟未分配的指针将是不确定的行为。但是sizeof
仅确定表达式的对象大小,而不实际对其求值。