我想创建一个整数指针p,为10个元素的数组分配内存,然后用值5填充每个元素。这是我的代码:
//Allocate memory for a 10-element integer array.
int array[10];
int *p = (int *)malloc( sizeof(array) );
//Fill each element with the value of 5.
int i = 0;
printf("Size of array: %d\n", sizeof(array));
while (i < sizeof(array)){
*p = 5;
printf("Current value of array: %p\n", *p);
*p += sizeof(int);
i += sizeof(int);
}
我在这段代码中添加了一些打印语句,但我不确定它是否实际上是用值5填充每个元素。
那么,我的代码是否正常工作?谢谢你的时间。
答案 0 :(得分:3)
首先:
*p += sizeof(int);
这将获取p
所指向的内容,并将整数的大小添加到其中。这没有多大意义。你可能想要的只是:
p++;
这使p
指向下一个对象。
但问题是p
包含指向第一个对象的唯一指针副本。因此,如果您更改其值,您将无法再访问内存,因为您将没有指向它的指针。 (所以你应该保存从某个地方malloc
返回的原始值的副本。如果没有别的,你最终还是需要它传递给free
。)
while (i < sizeof(array)){
这没有意义。您不希望循环次数等于数组占用的 bytes 的数量。
最后,您不需要任何数组。只需删除它并使用:
int *p = malloc(10 * sizeof(int));
对于C,请不要转换malloc
的返回值。它不是必需的,可以掩盖其他问题,例如未能包含正确的标题。对于while
循环,只需跟踪单独变量中的元素数量。
答案 1 :(得分:2)
sizeof
返回数组占用的字节数,以字节为单位。
int *p = (int *)malloc( sizeof(array) );
如果您致电malloc,则必须#include <stdlib.h>
。此外,演员阵容是不必要的,并且可能会引入危险的错误,尤其是在与缺少的malloc
定义配对时。
如果将指针递增1,则会到达指针类型的下一个元素。因此,您应该将底部写为:
for (int i = 0;i < sizeof(array) / sizeof(array[0]);i++){
*p = 5;
p++;
}
答案 2 :(得分:2)
这是一种更惯用的做事方式:
/* Just allocate the array into your pointer */
int arraySize = 10;
int *p = malloc(sizeof(int) * arraySize);
printf("Size of array: %d\n", arraySize);
/* Use a for loop to iterate over the array */
int i;
for (i = 0; i < arraySize; ++i)
{
p[i] = 5;
printf("Value of index %d in the array: %d\n", i, p[i]);
}
请注意,您需要分别跟踪数组大小,无论是在变量(我已经完成)还是宏(#define
语句)或只是整数文字。但是,使用整数文字很容易出错,因为如果以后需要更改数组大小,则需要更改更多行代码。
答案 3 :(得分:1)
*p += sizeof(int);
应该是
p += 1;
因为指针的类型为int *
也应该像这样计算数组大小:
sizeof (array) / sizeof (array[0]);
实际上,您的代码不需要该数组。
答案 4 :(得分:1)
//allocate an array of 10 elements on the stack
int array[10];
//allocate an array of 10 elements on the heap. p points at them
int *p = (int *)malloc( sizeof(array) );
// i equals 0
int i = 0;
//while i is less than 40
while (i < sizeof(array)){
//the first element of the dynamic array is five
*p = 5;
// the first element of the dynamic array is nine!
*p += sizeof(int);
// incrememnt i by 4
i += sizeof(int);
}
这将数组的第一个元素设置为9次,10次。看起来你想要更像的东西:
//when you get something from malloc,
// make sure it's type is "____ * const" so
// you don't accidentally lose it
int * const p = (int *)malloc( 10*sizeof(int) );
for (int i=0; i<10; ++i)
p[i] = 5;
___ * const
阻止您更改p
,以便始终指向已分配的数据。这意味着free(p);
将始终有效。如果更改p,则无法释放内存,并且内存泄漏。
答案 5 :(得分:1)
不,不是。但是,以下代码。你应该阅读指针算术。 p + 1是下一个整数(这是指针具有类型的原因之一)。还要记住,如果更改p的值,它将不再指向记忆的开头。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define LEN 10
int main(void)
{
/* Allocate memory for a 10-element integer array. */
int array[LEN];
int i;
int *p;
int *tmp;
p = malloc(sizeof(array));
assert(p != NULL);
/* Fill each element with the value of 5. */
printf("Size of array: %d bytes\n", (int)sizeof(array));
for(i = 0, tmp = p; i < LEN; tmp++, i++) *tmp = 5;
for(i = 0, tmp = p; i < LEN; i++) printf("%d\n", tmp[i]);
free(p);
return EXIT_SUCCESS;
}
答案 6 :(得分:1)
//Allocate memory for a 10-element integer array.
int array[10];
int *p = (int *)malloc( sizeof(array) );
此时,您已经为堆栈上分配的数组中的10个整数分配了两倍的内存空间,并为堆上分配的10个整数分配了空间。在一个需要为十个整数分配空间的“真正”程序中,堆栈分配不是正确的事情,分配将如下所示:
int *p = malloc(10 * sizeof(int));
请注意,无需从malloc(3)
转换返回值。我希望您忘记包含<stdlib>
标题,这将正确地对函数进行原型化,并为您提供正确的输出。 (如果没有标题中的原型,C编译器会假定函数将返回int
,并且强制转换使其将其视为指针。铸造在二十年内不是必需的。)
此外,要谨慎学习习惯sizeof(array)
。这将在代码中工作,其中数组与sizeof()
关键字在同一个块中分配,但在使用时会失败:
int foo(char bar[]) {
int length = sizeof(bar); /* BUG */
}
它看起来正确,但sizeof()
实际上会看到char *
而不是完整数组。 C的新Variable Length Array支持很敏锐,但不要误解为知道其大小的阵列在许多其他语言中可用。
//Fill each element with the value of 5.
int i = 0;
printf("Size of array: %d\n", sizeof(array));
while (i < sizeof(array)){
*p = 5;
*p += sizeof(int);
啊哈!我做过C指针同样麻烦的人!我认为你过去常常编写汇编代码而不得不自己增加指针? :)编译器知道p
指向的对象的类型(int *p
),因此如果只写p++
,它将正确地将指针移动正确的字节数。如果您将代码更改为使用long
或long long
或float
或double
或long double
或struct very_long_integers
,编译器将始终执行正确的操作有p++
的东西。
i += sizeof(int);
}
虽然那不是错误,但重新编写最后一个循环肯定会更加惯用:
for (i=0; i<array_length; i++)
p[i] = 5;
当然,你必须将数组长度存储到一个变量或#define
中,但这样做比依赖有时挑剔的数组长度更容易。
<强>更新
在阅读其他(优秀)答案后,我意识到我忘了提及由于p
是您对数组的唯一引用,因此最好不更新p
而不存储副本它的价值在某处。我的小'惯用'重写方面 - 解决问题,但没有指出为什么使用订阅比递增指针更惯用 - 这也是订阅首选的一个原因。我也更喜欢订阅,因为通常更容易推理数组基础不会改变的代码。 (这取决于。)