【问题标题】:How to Dynamically allocate the array size of your char variable based on the length of the user's input?如何根据用户输入的长度动态分配 char 变量的数组大小?
【发布时间】:2020-10-03 18:50:05
【问题描述】:

我需要让用户输入他的名字并将其存储在一个数组char 中,这个数组的大小是动态定位的,取决于他输入的用户名。

这是我的代码:

#include <stdio.h>
void main()
{
    static int size = 5 ;
    printf("please Enter Your First Name..\n");

    char* p = (char*)malloc(size*sizeof(char));

    for(int i = 0 ; i <= sizeof(p) ; i++)
    {
        if(sizeof(p)+1 == size )
        {
            p = (char*)realloc(p,2*size*sizeof(char));
            size = sizeof(p);
        }
        else
        {
            scanf("%c",&p[i]);
        }

    }
    for(int i = 0 ; i <=size ; i++)
    {
        printf("%s",*(p+i));
    }

free(p);

}

我给数组的第一个大小为5char,那么如果用户名长度大于这个大小,它在堆中重新分配大小的两倍,

我创建了一个条件 if(sizeof(p)+1 == size ) 因为 sizeof(p) = 4 ,所以我需要 5 = 5 所以我输入了 sizeof(p)+1

但我的代码不起作用。为什么?

【问题讨论】:

  • 我会通过分配一个足够大的缓冲区来做到这一点,然后通过重新分配缩小到大小。为每个角色重新定位是非常低效的。如果您必须使用这种方法,IMO 最好以 8 个字节的块工作(换句话说,当您用完空间时分配 8 个字节)。内存分配的粒度不太可能比这更好,因此您不会浪费内存。
  • @WeatherVane,我想创建一个缓冲区,但我认为它会是一样的,因为我给了数组的初始大小
  • sizeof(p) 是干什么用的?那是缓冲区 pointer 的大小而不是缓冲区的大小。您无法获得内存分配的大小,除非使用您自己的变量进行跟踪。您需要两个变量,一个用于缓冲区大小,一个用于您已使用的数量。
  • @WeatherVane 指针大小,
  • 好吧,sizeof(p)+1 将始终给出相同的值,无论您进行多少重新分配。

标签: arrays c pointers heap-memory


【解决方案1】:

一个常见的错误是使用sizeof(pointer) 来获取它指向的内存大小。这里有一些示例代码供您尝试。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>             // required header files

#define CHUNK 1  // 8           // amount to allocate each time

int main(void)                  // correct definition
{
    size_t size = CHUNK;        // prefer a larger size than 1
    size_t index = 0;
    int ch;                     // use the right type for getchar()
    char *buffer = malloc(size);
    if(buffer == NULL) {
        // handle erorr
        exit(1);
    }

    printf("Please enter your first name\n");
    while((ch = getchar()) != EOF && ch != '\n') {
        if(index + 2 > size) {       // leave room for NUL
            size += CHUNK;
            char *temp = realloc(buffer, size);
            if(temp == NULL) {
                // handle erorr
                exit(1);
            }
            buffer = temp;
        }
        buffer[index] = ch;
        index++;
    }

    buffer[index] = 0;               // terminate the string
    printf("Your name is '%s'\n", buffer);
    printf("string length is %zu\n", strlen(buffer));
    printf("buffer size   is %zu\n", size);

    free(buffer);
    return 0;
}

节目环节:

Please enter your first name
Weather
Your name is 'Weather'
string length is 7
buffer size   is 8

我更喜欢使用更大的缓冲区大小,因为这样对系统的压力较小,而且分配的内存可能无论如何都使用最小大小。当我设置

#define CHUNK 8

会话是

Please enter your first name
Wilhelmina
Your name is 'Wilhelmina'
string length is 10
buffer size   is 16

【讨论】:

  • 谢谢主人,你让我很开心,但我有一个问题,如果(索引 + 2 > 大小)这种情况的目的是什么?
  • 缓冲区必须足够大以容纳下一个字符 NUL 终止符(写在循环之后)。数组的初始大小为1,如果第一个字符是换行符,则得到空字符串。
  • 你好兄弟,什么意思 buffer[index] = ch;为什么我需要这条线?这个缓冲区[索引] = 0;
  • buffer[index] = ch; 正在构建您键入的字符数组。 buffer[index] = 0; 正在编写使其成为字符串所需的 nul 终止符。
猜你喜欢
  • 2020-11-11
  • 2011-11-08
  • 1970-01-01
  • 2022-11-13
  • 2015-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
相关资源
最近更新 更多