我是一名学生,下周将参加C语言中的动态内存分配考试。我正在查看旧的测试题,并且遇到了一个说:
编写一个C程序,动态创建一个长度为30,000的单维数组,并使用0到9之间的随机数初始化该数组。
我对如何创建随机数并将它们放入数组有了深刻的理解,但我对我的malloc语句以及除了' sizeof'之外的其他数字感到困惑。里面的代码。例如,我有这个代码为float分配内存:
#include<stdio.h>
#include<stdlib.h>
float* func();
int main(void)
{
int i;
float* x;
float array[0];
x=func();
srand(time(NULL));
i=random()%10;
array[i];
}
float * func(void)
{
float z;
float* ptr;
ptr = malloc(30000 * sizeof(float));
if(ptr == NULL)
{
puts("ALLOCATION FAILED.\n");
}else{
ptr = &z;
return ptr;
}
}
我的问题是如何为长度为30,000的单维数组动态分配内存?这种分配对现实世界的软件开发工作有什么用?
答案 0 :(得分:4)
或许使用ptr = calloc(30000, sizeof(float));
更有意义。第一个参数是内存块中的元素数量(即一个大小为30 000的数组)。第二个参数是一个块的大小(即数组中的一个元素)。
所以你这样称呼它:
calloc
在您的情况下使用malloc
存在一个瓶颈,因为将内存清零可能需要一些时间。您可以使用ptr
执行相同的操作,而不是执行此操作,使ptr = malloc(30000 * sizeof(float));
未初始化。
calloc
另请don't cast结果malloc
或func
。
编辑:由于您更改了问题以解决首次提出的问题,因此您的代码还存在其他一些问题。从格式化问题开始,您应该在include指令后添加空格。此外,您的原型不正确,因为它表示void
可以接受任何数量的参数,因为它指定了具有未定义参数的函数,因此您应该使用关键字#include <stdio.h>
#include <stdlib.h>
float* func(void);
代替:
array
稍后在函数定义中,中间有星号,而原型中则为左侧。请保持一致。
你的random()
声明是多余的,因为你从不使用它(至少你不应该因为你为动态数组分配内存)。
您在动态数组中设置数字的逻辑无效。您尝试使用0到9之间的随机索引来访问空的静态数组,这很可能会崩溃。我想你想要遍历动态数组的每个元素并分配0到9之间的随机整数,最后rand()
不是C中的函数;你想要x=func(); // allocate memory for x
srand(time(NULL)); // set a random seed for psuedo-random functions
for(i=0;i<30000;i++) {
x[i] = rand() % 10; // assign a random number between 0 and 9.
}
:
puts
在您分配内存的函数中,您将使用一个整数数组覆盖指向动态数组的指针,这会在以后尝试访问它时使程序崩溃,因为它没有分配给它的内存。您还可以将perror
错误消息替换为 ptr = malloc(30000 * sizeof(float));
if(ptr == NULL) {
perror("malloc failed");
// handle error
}else {
return ptr;
}
,以获取有关分配失败原因的更详细信息。
{{1}}
答案 1 :(得分:2)
您的代码中存在很多错误。我会尝试列出它们(每行后面的文字):
float* func(void);
使用prototype-declarators。 C不是C ++!
float array[0];
这是没用的,因为你应该动态分配一个数组 。
x=func();
分配可能会失败。 始终检查错误: if((x = func)== NULL){ printf(&#34;分配失败。&#34;); 出口(1); }
i=random()%10;
array[i];
i
未初始化。你需要在x
指向的所有元素上循环。 array
只是一个本地数组。这是未定义的行为。避免像地狱(或任何你最害怕的)。
float * func(void)
这里有趣的是你有正确的类型。请注意,这与上面的声明不同!启用编译器警告并注意它们,编译器应该抱怨。
float z;
为什么?
ptr = malloc(30000 * sizeof(float));
这是一个好东西:这是正确的!你不应该在C中投射void *
。
if(ptr == NULL)
{
puts("ALLOCATION FAILED.\n");
好的,你在这里有消息。但你仍然回来,所以打电话者也必须检查。除非你exit(1)
已经准备好了 - 这是允许的,但不是好的风格。
ptr = &z;
在此处覆盖指向已分配数组的指针并将其设置为 local 变量。你也不能free
已分配的数组,因为你丢失了它的地址。
只需删除此行以及z
的定义;它们没用(而且这条线也错了)。 这是主要错误
return ptr;
现在返回无效的内存地址。 从不返回本地变量的地址。一旦离开定义的块(这里:函数),这就会过时。