使用动态内存分配的程序在c中获取未知大小的字符串
a program using dynamic memory allocation to take a string of unknown size in c
我正在编写一个程序,用户将输入一个未知大小的字符串,如果用户输入“END”,程序将终止,否则,它将要求输入另一个字符串和另一个
由于字符串的大小未知,我使用动态内存分配来获取未知大小的字符串
这是我尝试过的
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
bool on = true;
char *string;
while(on)
{
string = malloc(sizeof(char));
int i;
for (i = 0;; i++)
{
int n;
n = getchar();
if (n == '\n')
{
break;
}
else
{
string = realloc(string, sizeof(char));
string[i] = (char)n;
}
}
string[i] = '[=10=]';
if (strcmp(string, "END") == 0)
{
on = false;
}
printf("Len: [%i],String = %s\n",i+1,string);
free(string);
}
return 0;
}
但是如果我输入一个大小超过 25 左右的字符串,程序就会崩溃,它会给我这个输出
0 [main] get_the_line_dynamically 1056 cygwin_exception::open_stackdumpfile: Dumping stack trace to get_the_line_dynamically.exe.stackdump
但是,这段代码有什么问题??
realloc()
分配您指定的大小,当大小增加时,它将数据从原始分配复制到新分配,然后 returns 将旧数据复制到堆中。它不是 incremental 您传递的大小是绝对大小,而不是大小 increase.
因此你需要:
string = realloc( string, i + 2 ) ;
然而,以单个字节递增是非常低效的,需要为每个单个字节分配、数据复制和释放。正常的过程是以更大的块增加容量,并且只有在超过当前容量时才增加分配。所以你可能有:
#define STRING_CAPACITY_INCREMENT 32
size_t string_capacity = STRING_CAPACITY_INCREMENT ;
char* string = malloc( string_capacity ) ;
然后:
// If insufficient capacity for new character plus NUL...
if( i + 2 > string_capacity )
{
string_capacity += STRING_CAPACITY_INCREMENT ;
string = realloc(string, string_capacity );
}
string[i] = (char)n;
这将提高时间性能,但如果您担心内存使用,请记住内存分配是 8 字节对齐的,因此与 8 的容量增量相比,单字节增量不会节省任何东西。同样出于这个原因,增量也应该是 8 的倍数。
在某些情况下,您可能会选择指数容量增加,例如加倍:8、16、32、64 等到某个合理的极限,然后变为线性。如果您有很多小字符串而只有几个长字符串,那么在平衡性能和内存使用方面可能会更好。
我正在编写一个程序,用户将输入一个未知大小的字符串,如果用户输入“END”,程序将终止,否则,它将要求输入另一个字符串和另一个 由于字符串的大小未知,我使用动态内存分配来获取未知大小的字符串 这是我尝试过的
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
bool on = true;
char *string;
while(on)
{
string = malloc(sizeof(char));
int i;
for (i = 0;; i++)
{
int n;
n = getchar();
if (n == '\n')
{
break;
}
else
{
string = realloc(string, sizeof(char));
string[i] = (char)n;
}
}
string[i] = '[=10=]';
if (strcmp(string, "END") == 0)
{
on = false;
}
printf("Len: [%i],String = %s\n",i+1,string);
free(string);
}
return 0;
}
但是如果我输入一个大小超过 25 左右的字符串,程序就会崩溃,它会给我这个输出
0 [main] get_the_line_dynamically 1056 cygwin_exception::open_stackdumpfile: Dumping stack trace to get_the_line_dynamically.exe.stackdump
但是,这段代码有什么问题??
realloc()
分配您指定的大小,当大小增加时,它将数据从原始分配复制到新分配,然后 returns 将旧数据复制到堆中。它不是 incremental 您传递的大小是绝对大小,而不是大小 increase.
因此你需要:
string = realloc( string, i + 2 ) ;
然而,以单个字节递增是非常低效的,需要为每个单个字节分配、数据复制和释放。正常的过程是以更大的块增加容量,并且只有在超过当前容量时才增加分配。所以你可能有:
#define STRING_CAPACITY_INCREMENT 32
size_t string_capacity = STRING_CAPACITY_INCREMENT ;
char* string = malloc( string_capacity ) ;
然后:
// If insufficient capacity for new character plus NUL...
if( i + 2 > string_capacity )
{
string_capacity += STRING_CAPACITY_INCREMENT ;
string = realloc(string, string_capacity );
}
string[i] = (char)n;
这将提高时间性能,但如果您担心内存使用,请记住内存分配是 8 字节对齐的,因此与 8 的容量增量相比,单字节增量不会节省任何东西。同样出于这个原因,增量也应该是 8 的倍数。
在某些情况下,您可能会选择指数容量增加,例如加倍:8、16、32、64 等到某个合理的极限,然后变为线性。如果您有很多小字符串而只有几个长字符串,那么在平衡性能和内存使用方面可能会更好。