使用malloc和realloc将静态数组更改为动态数组?

使用malloc和realloc将静态数组更改为动态数组?,c,arrays,malloc,stdin,realloc,C,Arrays,Malloc,Stdin,Realloc,下面的代码读取stdin并将其放入stdout,但顺序相反。我使用了一个静态数组,因为我知道input.txt中有多少字符。我的问题是如何使用malloc和realloc更改动态数组(指针)中的数组?我所有的尝试都失败了 #include <stdio.h> #include <stdlib.h> int main() { char ch; int i,counter; char array[50]; counter = 0

下面的代码读取stdin并将其放入stdout,但顺序相反。我使用了一个静态数组,因为我知道input.txt中有多少字符。我的问题是如何使用malloc和realloc更改动态数组(指针)中的数组?我所有的尝试都失败了

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



    int main()
{
    char ch;
    int i,counter;
    char array[50];

    counter = 0;
    i = 0;

    while((ch=getchar()) != EOF)
    {

        array[i] = ch;
        i++;
        counter++;

    }

    for(i = (counter + 1); i >= 0; i--)
    {
        printf("%c",array[i]);
    }

    printf("\n");

    return 0;
}
#包括
#包括
int main()
{
char ch;
int i,计数器;
字符数组[50];
计数器=0;
i=0;
而((ch=getchar())!=EOF)
{
数组[i]=ch;
i++;
计数器++;
}
对于(i=(计数器+1);i>=0;i--)
{
printf(“%c”,数组[i]);
}
printf(“\n”);
返回0;
}
显而易见的解决方案:

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

void readandprint(void)
{
  int c = getchar();
  if (c == EOF)
    return;
  readandprint();
  printf("%c", c);
  return;
}

int main()
{
  readandprint();
  printf("\n");
  return 0;
}
#包括
#包括
作废读取和打印(作废)
{
int c=getchar();
如果(c==EOF)
返回;
readandprint();
printf(“%c”,c);
返回;
}
int main()
{
readandprint();
printf(“\n”);
返回0;
}
#包括
#包括
内部主(空){
int ch;//必须为int才能与EOF进行比较。
int i,计数器;
char*array=malloc(50);
int size=50;
计数器=0;
而((ch=getchar())!=EOF){
数组[计数器+++]=ch;
如果(计数器==大小){
char*temp=realloc(数组,大小+=50);
if(temp==NULL){
自由(数组);
fprintf(标准,“realloc错误!\n”);
返回-1;
}
数组=温度;
}
}
while(柜台){
printf(“%c”,数组[--计数器]);
}
自由(数组);
返回0;
}

即使您知道您使用的输入从未超过50个字符,您也应该强制执行该限制。当程序以任意输入运行时,您最终将访问数组末端以外的数据

总之,这是您的程序核心,提取到函数中:

void rev1()
{
    char array[50];     // Allocate 50 bytes on the stack
    int i = 0;
    char ch;

    while (i < 50 && (ch = getchar()) != EOF) array[i++] = ch;    
    while (i--) putchar(array[i]);
    printf("\n");

    // Do nothing - array goes out of scope
}
注意事项:

  • sizeof(*array)
    在本例中是
    sizeof(char)
    ,它总是1,因此经常被忽略。但是
    p=malloc(count*sizeof(*p))
    是一种非常有用的分配模式,用于分配
    count
    元素数组,如果您更改指向的对象的类型,这些元素仍然有效

  • 堆上的内存分配可能失败
    malloc
    然后将返回
    NULL
    。你必须应付这种情况。简单的策略是只打印一条错误消息并中止程序。根据您需要的内存,您可能会选择其他失败策略

  • 请注意,作为函数的核心,循环与第一个版本完全相同

  • 您还必须强制执行50个字符的限制。数组在堆上,但没有增长

  • 使用后释放内存。如果你不这样做,你就会“泄漏内存”,也就是说,你会阻止内存块。这里,
    array
    ——保存数组的指针变量,而不是数组本身——是超出范围的局部变量。忘记释放这里的内存意味着您丢失了它的地址,无法再次访问它

  • 变量
    数组
    指向内存的开始。此变量必须传递给
    自由
    。不要更改此变量,例如通过增加它,否则将丢失内存的“键”

稍微复杂一点的版本会根据需要重新分配内存。如果数组增长,可以使用
realloc
而不是
malloc
。即使内存不相同,已分配的数据仍保持不变:

void rev3()
{
    char *array = NULL;     // Initially unallocated NULL array
    size_t size = 0;        // Allocated size, initially 0
    int i = 0;
    char ch;

    while ((ch = getchar()) != EOF) {
        if (i >= size) {                    // Check current bounds
            size += 50;                     // Increase memory
            array = realloc(array,          // Reallocate
                size * sizeof(*array));
            if (array == NULL) exit(1);
        }
        array[i++] = ch;    
    }

    while (i--) putchar(array[i]);
    printf("\n");

    free(array);        // Explicitly release data after use
}
注:

  • realloc(NULL,size)
    的行为类似于
    malloc(size)
    。因此,您可以通过从
    NULL
    指针开始,轻松实现重新分配方案

  • 尽管内核在内部跟踪分配的大小,但您没有办法知道它,因此您必须自己跟踪此信息,在本例中使用
    size

  • 同样,您必须确保分配成功。我在上面使用了快速、肮脏(和无声)的程序终止,但您可以选择其他策略

  • 在这种情况下,核心循环更为复杂。在添加到内存之前,必须检查是否应增加内存。填充内存后,访问(在分配的边界内)将照常进行


您实际尝试了什么?您当前的代码仍然有静态数组。我有很多错误,所以我认为最好发布代码,这实际上是可行的。好吧,如果我们没有看到失败的代码,我们就无能为力,可以吗?听起来不错。我会再试一次,然后在静态数组代码下面发布代码。好吧,问题是我不知道如何正确使用它们。很多页面有很多不同的使用方法,但没有任何方法可以帮助我。有人能帮我吗?对不起,我不明白这个问题的答案。@student96:你试过了吗?没有,我应该用这个代码做什么?你如何使用函数本身?@student96:它被称为
递归
。那些不理解它的人注定要重复它。C程序的传统做法是编译并运行它们。
void rev2()
{
    char *array;
    int i = 0;
    char ch;

    array = malloc(50 * sizeof(*array));    // Allocate on the heap
    if (array == NULL) exit(1);             // Check for failure

    while (i < 50 && (ch = getchar()) != EOF) array[i++] = ch;    
    while (i--) putchar(array[i]);
    printf("\n");

    free(array);        // Explicitly release data after use
}
void rev3()
{
    char *array = NULL;     // Initially unallocated NULL array
    size_t size = 0;        // Allocated size, initially 0
    int i = 0;
    char ch;

    while ((ch = getchar()) != EOF) {
        if (i >= size) {                    // Check current bounds
            size += 50;                     // Increase memory
            array = realloc(array,          // Reallocate
                size * sizeof(*array));
            if (array == NULL) exit(1);
        }
        array[i++] = ch;    
    }

    while (i--) putchar(array[i]);
    printf("\n");

    free(array);        // Explicitly release data after use
}