【问题标题】:How to dynamically allocate memory for a single dimension array of length 30,000?如何为长度为 30,000 的单维数组动态分配内存?
【发布时间】:2015-11-02 16:07:13
【问题描述】:

我是一名学生,正在准备下周的 C 动态内存分配测试。我正在查看旧的测试问题,并且遇到了一个问题:

编写一个 C 程序,动态创建一个长度为 30,000 的单维数组,并用 0 到 9 的随机数初始化该数组。

我对如何创建随机数并将它们放入一个数组有深刻的理解,但我对我的 malloc 语句以及如何在其中放置除“sizeof”代码之外的数字感到困惑。例如,我有这个为浮点分配内存的代码:

#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 的单维数组动态分配内存?这种分配对于现实世界的软件开发工作有什么用处?

【问题讨论】:

  • 在 C 中你应该 not cast the result of malloc(或其他返回 void * 的函数)。
  • 至于你的问题,你再想想。如果malloc(sizeof(float)) 分配了一个float,你怎么能把它改成分配两个呢?也许像malloc(sizeof(float) + sizeof(float)) 这样的东西?这怎么能概括为分配 N 个元素?
  • 刚刚注意到你完全改变了你的问题。回滚到以前的状态。您不得更改问题的核心,因为这会删除答案的上下文。如果您有什么要补充的,只需在原始问题上附加适当的注释和新信息即可。

标签: c arrays memory memory-management


【解决方案1】:

也许使用calloc 更有意义。第一个参数是内存块中元素的数量(即大小为 30 000 的数组)。第二个参数是一个块的大小(即数组中的一个元素)。

所以你可以这样称呼它:

ptr = calloc(30000, sizeof(float));

在您的情况下使用calloc 存在一个瓶颈,因为将内存归零可能需要一些时间。你可以用malloc 做同样的事情,但你会这样做,这会使ptr 未初始化。

ptr = malloc(30000 * sizeof(float));

也请don't castcallocmalloc 的结果。

编辑:由于您更改了问题以解决您首先提出的问题,因此您的代码还有其他几个问题。从格式问题开始,您应该在 include 指令之后添加一个空格。此外,您的原型也不正确,因为它说 func 可以接受 任何 数量的参数,因为它指定了一个带有未定义参数的函数,因此您应该改用关键字 void

#include <stdio.h>
#include <stdlib.h>

float* func(void);

稍后在您的函数定义中,星号位于中间,而在原型中则位于左侧。请保持一致。

而且您对array 的声明是多余的,因为您从不使用它(至少您不应该这样做,因为您为动态数组分配内存)。

您在动态数组中设置数字的逻辑不起作用。您正在尝试使用 0 到 9 之间的随机索引访问空静态数组,这很可能会崩溃。我认为您的意思是遍历动态数组的每个元素并分配一个介于 0 和 9 之间的随机整数,最后 random() 不是 C 中的函数;你想要rand():

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;
 }

【讨论】:

  • 值得指出的是,calloc() 还将其分配的内存初始化为二进制零。如果您之后只是想用随机数填充数组,则没有必要这样做。
  • 这不会消除错误。并且问题已经包含这一行。
  • @Olaf 他改变了他的问题,看看历史。
  • @Linus:我现在明白了。那时你应该标记。更改问题的含义并使答案无效是违反 SO 的规则的。或编辑您的答案;他的代码还有很多问题。 OP 的考试有很多内容要学习。
  • @Olaf 标记它做什么?
【解决方案2】:

您的代码中有很多错误。我将尝试列出它们(每行后的文字):

float* func(void);

使用原型声明符。 C 不是 C++!

float array[0];

这是没用的,因为你应该动态地分配一个数组

x=func();

分配可能会失败。 始终检查错误: if ( (x = func) == NULL ) { printf("分配失败。"); 退出(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;

现在您返回一个无效的内存地址。 从不返回局部变量的地址。一旦你离开它定义的块(这里:函数),它就会消失。

【讨论】:

    猜你喜欢
    • 2021-07-21
    • 1970-01-01
    • 2015-11-04
    • 2012-11-12
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2020-07-11
    相关资源
    最近更新 更多