尝试理解C中的内存分配。在尝试使用指向整数的指针创建两个数组时遇到问题。请看下面的代码:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *a;
int *b;
for (int i = 0; i<4;i++)
{
printf("Enter value \n");
a[i]=(int *)malloc(sizeof(int));
b[i]=(int *)malloc(sizeof(int));
scanf("%d",&a[i]);
scanf("%d",&b[i]);
}
for (int i =0;i<4;i++)
{
printf("%d = %x\n ",a[i],&a[i]);
}
for (int i =0;i<4;i++)
{
printf("%d = %x\n ",b[i],&b[i]);
}
return 0;
}
我在CLion上使用C11。面对运行时的错误。有人可以解释一下这段代码有什么问题吗?
Enter value
Process finished with exit code 11
“b在调试期间显示为NULL”
更新: 试过另一个IDE,其中“a”本身没有被分配任何内存。它直接给我分段错误。
更新2: 改变:
int *a;
int *b;
到
int *a = NULL;
int *b = NULL;
至少停止此代码的行为方式。一旦我尝试将内存分配给[i](这是错误的,现在我得到),它就会给我分段错误。
答案 0 :(得分:2)
虽然代码确实为四个int
值分配内存,但它并不像您期望的那样工作。
如果我们从头开始:
int *a;
这定义(并声明)变量a
,它是指向int
的指针。你没有初始化它,这意味着它的值是不确定(并且看起来完全是随机的)。取消引用此功能(例如a[i]
)会导致undefined behavior。
然后
for (int i = 0; i<4;i++)
{
a[i]=(int *)malloc(sizeof(int));
...
}
如果您正确初始化了a
,那么它已经指向四个int
值的内存。您可以将a
视为数组,并且不需要分别分配数组的每个成员。这由类型表示,a[i]
属于int
类型,而不是int *
。
&#34; best&#34;解决方案是根本不使用指针或动态分配,而是使用普通数组:
int a[4];
for (int i = 0; i<4;i++)
{
printf("Enter value \n");
scanf("%d",&a[i]); // No allocation needed, a[i] already exists
}
如果必须使用指针和动态分配,那么为4个int
元素分配足够的内存,并使a
指向第一个字节:
int *a = malloc(sizeof(int) * 4);
for (int i = 0; i<4;i++)
{
printf("Enter value \n");
scanf("%d",&a[i]); // No allocation needed, a[i] already exists
}
还有一些其他问题,但从这些问题开始。
答案 1 :(得分:1)
您的代码中存在一些混淆:
a
和b
分配数组以指向。 a
和b
未初始化,取消引用它们具有未定义的行为。 a
在调试器中显示为NULL
,但C标准并不保证。 a
可以具有任何值,包括仅通过读取就会导致未定义行为的陷阱表示。int
的指针存储到a[i]
中:编译器应发出有关类型不匹配的诊断信息。不幸的是,这不是一个致命的错误恕我直言,但忽略编译器警告总是一个坏主意。malloc()
的返回值为(int *)
。这在C ++中是必要的,但在C中被认为是坏的风格。printf("%d = %x\n", a[i], &a[i]);
中的第三个参数与转换说明符不一致:如果要以十六进制格式打印值,请使用printf("%d = %x\n", a[i], a[i]);
,如果要打印地址,请使用{{1}转换说明符:%p
要使用printf("%d at %p\n", a[i], (void*)&a[i]);
,您应该只分配malloc()
数组,检查分配成功并在使用后释放内存:
int
答案 2 :(得分:0)
您需要添加这些行,因为您需要创建内存以便以后可以分配值:
int **a = (int **)malloc(sizeof(int *) * 4);
int **b = (int **)malloc(sizeof(int *) * 4);
您正在为a
的元素指定指针值。因此a
应该是指向指针的指针。
完整代码:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int **a = (int **)malloc(sizeof(int *) * 4);
int **b = (int **)malloc(sizeof(int *) * 4);
for (int i = 0; i < 4; i++)
{
printf ("Enter value \n");
a[i] = (int *) malloc (sizeof (int));
b[i] = (int *) malloc (sizeof (int));
scanf ("%d", &a[i]);
scanf ("%d", &b[i]);
}
for (int i = 0; i < 4; i++)
{
printf ("%d = %x\n ", a[i], &a[i]);
}
for (int i = 0; i < 4; i++)
{
printf ("%d = %x\n ", b[i], &b[i]);
}
return 0;
}
输出:
Enter value
4
5
Enter value
1
2
Enter value
6
7
Enter value
8
9
4 = 165d010
1 = 165d018
6 = 165d020
8 = 165d028
5 = 165d040
2 = 165d048
7 = 165d050
9 = 165d058