【问题标题】:Deciding how much memory to dynamically allocate based on user input根据用户输入决定动态分配多少内存
【发布时间】:2015-03-03 04:25:18
【问题描述】:

我需要编写一个执行以下操作的程序:

  • 提示用户并询问他们希望输入多少字
  • 使用 malloc() 分配动态内存来存储每个单词
  • 动态分配另一个数组来存储指向每个单词字符串的指针,用指针填充它
  • 动态分配一个额外的数组来临时存储传入的单词
  • 提示用户输入与之前输入的字数相同的字符串。
  • 一次将用户的输入读入临时数组中的一个单词,读取完每个单词后,将其传输到动态分配的数组中。
  • 完成所有这些之后,我应该能够单独打印每个单词。

示例运行可能如下所示:

How many words do you wish to enter? 5 
Enter 5 words now:
I enjoyed doing this exercise
Here are your words:
I 
enjoyed 
doing 
this 
exercise

在读取字符串时,程序应该将单词读入一个临时的char数组中,使用malloc()分配足够的存储空间来保存单词,并将地址存储在char指针数组中。这一步如何处理?

这是我的问题:如何调整我的临时数组的大小,使其足够大以容纳用户可能输入的任意单词,然后如何将其传输到存储数组?

#include <stdio.h>
#include <stdlib.h>
enum { MAX_WORD_SIZE = sizeof("Supercalifragilisticexpialidocious") };
void resign(char**,int);
int main()
{
    char **p;
    int n,i;
    printf("How many words do you wish to enter?");
    scanf("%d",&n);
    p=calloc(n, sizeof(char*));
    puts("Here are your words:");
    resign(p,n);
    for (i=0; i<n; i++) {
        puts(p[i]);
    }
}
 void resign(char**p,int n)
{
    int i=0,j=0;
    char c;
    char * temp_word = NULL;
    getchar();
    temp_word = malloc(MAX_WORD_SIZE);
        while ((c=getchar())!='\n') {
        if (c!=' ') temp_word[i++]=c;
        else {temp_word[i]='\0';
        p[j]=temp_word;
        temp_word = malloc(MAX_WORD_SIZE);
            i=0;j++;}
}
    temp_word[i]='\0';
    p[j]=temp_word;
    free(temp_word);
}

【问题讨论】:

  • 到目前为止你有什么?您的代码的哪些部分有问题?
  • 到目前为止您尝试过什么?你不会得到帮助发布问题并说你不知道该怎么做。你需要证明你已经做出了一些努力来尝试解决这个问题。
  • 读取字符串时,程序应该将单词读入一个临时的char数组中,使用malloc()分配足够的存储空间来保存单词,并将地址存储在char指针数组中。这一步怎么处理?
  • @usb-pineapple 我正在根据您想问的问题修改您的问题。

标签: c string pointers


【解决方案1】:

这里是malloc()的描述。

它接受一个参数size,以字节为单位。

所以如果用户输入了 5 个单词,那么你需要先分配一个足够大的数组来存储 5 个指针。

例如。

char ** words = NULL;
words = malloc(sizeof(char *) * <NUMBER OF CHARACTERS THE USER ENTERED>);

如果我们假设使用 ASCII 并且字符是 char,那么每个单词中的每个字母都是一个字节。我们还需要考虑任何空格、换行符、可能是回车符和结尾的空值。

那么一个单词有多少个字母? IDK,这取决于你。但是,如果我们假设"Supercalifragilisticexpialidocious" from Mary Poppins 在我们将遇到的最长单词中,那么我们需要分配至少 34 个字符,加上一个额外的用于尾随空终止符的字符。这样一来,我们每个字最多可以保留 35 个字节。

这将起作用:

enum { MAX_WORD_SIZE = sizeof("Supercalifragilisticexpialidocious") };

这还将考虑到尾随 \0 - MAX_WORD_SIZE 将为 35。

char * temp_word = NULL;
temp_word = malloc(MAX_WORD_SIZE);

要创建所有其他单词数组,您需要在循环中执行类似的操作:

for(int i = 0; i< <NUMBER OF WORDS THE USER ENTERED>; i++)
{
    words[i] = malloc(MAX_WORD_SIZE);
}

要将用户输入的单词数转换为整数,您应该使用atoi()

在此之后,您可以使用getchar() 一次从标准输入中提取一个字符并手动将它们放入您分配的临时位置,当您到达' ' 空间时停止。

要将临时数组复制到您可以使用strcpy() 的单词数组中,只需确保您的临时数组在单词后始终有一个尾标\0

完成后别忘了free()那个指针。

我假设您这样做是为了完成某种关于动态内存的家庭作业,这就是为什么您的应用程序是这样定义的。但是,如果您不是,您应该考虑先使用fgets() 将输入读入一个缓冲区,然后在读取字符串后使用strtok() 拆分字符串。这种方法会占用更多内存,但会更干净。

您应该考虑做的另一件事是使用calloc() 而不是malloc() 进行分配,这样您就可以确保所有数组都以0 初始化——如果有的话,它可以避免您以后出现一些混乱是那些数组中已经存在的垃圾数据。

还有一件事要考虑:这个例子中的临时数组可以使用temp_word[MAX_WORD_SIZE]; 自动或静态分配,因为我使用枚举将 MAX_WORD_SIZE 存储为常量。无需为此直接使用 malloc。

【讨论】:

    猜你喜欢
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 2014-03-18
    • 1970-01-01
    相关资源
    最近更新 更多