使用malloc和realloc将静态数组更改为动态数组?
下面的代码读取stdin并将其放入stdout,但顺序相反。我使用了一个静态数组,因为我知道input.txt中有多少字符。我的问题是如何使用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
#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)
,它总是1,因此经常被忽略。但是sizeof(char)
是一种非常有用的分配模式,用于分配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
- 同样,您必须确保分配成功。我在上面使用了快速、肮脏(和无声)的程序终止,但您可以选择其他策略
- 在这种情况下,核心循环更为复杂。在添加到内存之前,必须检查是否应增加内存。填充内存后,访问(在分配的边界内)将照常进行
递归
。那些不理解它的人注定要重复它。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
}