char数组中可以有多少个字符?

#define HUGE_NUMBER ??? char string[HUGE_NUMBER]; do_something_with_the_string(string); 

我想知道什么是我可以添加到char数组的最大数量,而不会冒任何潜在的内存问题,缓冲区溢出等风险。 我想让用户输入,也许最大可能。

请看Jack Klein的回复(参见原帖 ):

原始C标准(ANSI 1989 / ISO 1990)要求编译器成功转换至少一个包含一组环境限制的示例的程序。 其中一个限制是能够创建至少32,767字节的对象。

该最低限制在1999年对C标准的更新中提出至少为65,535字节。

提供大于该大小的对象不需要C实现,这意味着它们不需要允许大于(int)(65535 / sizeof(int))的int数组。

实际上,在现代计算机上,不可能事先说出可以创建多大的数组。 它可能取决于计算机中安装的物理内存量,操作系统提供的虚拟内存量,已运行的其他任务,驱动程序和程序的数量以及正在使用的内存量。 因此,您的程序今天可能会使用比昨天使用的更多或更少的内存,或者它将能够在明天使用。

许多平台对自动对象施加了最严格的限制,即在不使用’static’关键字的情况下在函数内定义的对象。 在某些平台上,如果它们是静态的或动态分配,则可以创建更大的数组。

现在,为了提供更加量身定制的答案,请不要声明巨大的arrays以避免缓冲溢出 。 这与C中可以想到的最差实践接近。相反,花一些时间编写好的代码,并仔细确保不会发生缓冲区溢出。 另外,如果您事先不知道arrays的大小,请查看malloc ,它可能会派上用场:P

它取决于char string[HUGE_NUMBER]; 被放置。

  • 它在function内吗? 然后arrays将在堆栈上,并且操作系统的增长速度 是否以及速度取决于操作系统。 所以这是一般规则:不要在堆栈上放置大型数组。

  • 它是一个函数然后它是全局的(进程内存),如果操作系统在尝试加载你的程序时不能分配那么多的内存,你的程序将崩溃,你的程序将没有机会注意到(所以以下是更好:)

  • 大型数组应该是malloc 。 对于malloc,如果malloc失败,操作系统将返回空指针,具体取决于操作系统及其分页方案和内存映射方案,当1)没有连续的空闲内存区域足够大时,它将失败。数组或2)操作系统无法将足够的空闲物理内存区域映射到作为连续内存对您的进程显示的内存。

因此,使用大型数组执行此操作:

 char* largeArray = malloc(HUGE_NUMBER); if(!largeArray) { do error recovery and display msg to user } 

声明任意大的数组以避免缓冲区溢出是不好的做法。 如果您事先并不知道缓冲区需要多大,请使用mallocrealloc根据需要动态分配和扩展缓冲区,可能使用较小的固定大小的缓冲区作为中介。

例:

 #define PAGE_SIZE 1024 // 1K buffer; you can make this larger or smaller /** * Read up to the next newline character from the specified stream. * Dynamically allocate and extend a buffer as necessary to hold * the line contents. * * The final size of the generated buffer is written to bufferSize. * * Returns NULL if the buffer cannot be allocated or if extending it * fails. */ char *getNextLine(FILE *stream, size_t *bufferSize) { char input[PAGE_SIZE]; // allocate int done = 0; char *targetBuffer = NULL; *bufferSize = 0; while (!done) { if(fgets(input, sizeof input, stream) != NULL) { char *tmp; char *newline = strchr(input, '\n'); if (newline != NULL) { done = 1; *newline = 0; } tmp = realloc(targetBuffer, sizeof *tmp * (*bufferSize + strlen(input))); if (tmp) { targetBuffer = tmp; *bufferSize += strlen(input); strcat(targetBuffer, input); } else { free(targetBuffer); targetBuffer = NULL; *bufferSize = 0; fprintf(stderr, "Unable to allocate or extend input buffer\n"); } } } 

如果要在堆栈上分配数组,那么您受到堆栈大小的限制( 在Windows上通常为1MB ,其中一些将被使用,因此您甚至更少)。 否则我想象限制会很大。

但是, 使arrays非常大并不能解决缓冲区溢出问题 。 不要这样做。 使用具有限制其缓冲区数量的机制的函数,以确保不会超出缓冲区,并使大小更合理(例如1K)。

您可以使用malloc()来获取比通常数组可以处理的更大的内存部分。

好吧,一个缓冲区溢出不会由于HUGE_NUMBER的值太大而导致太小而不是写入它的内容(写入索引HUGE_NUMBER或更高,并且你已经溢出缓冲区)。

除此之外,它将取决于机器。 当然系统可以处理堆中的数百万,堆栈上有一百万左右(取决于其他压力),但也有一些系统无法处理超过几百个(小型嵌入式设备将是一个明显的例子)。 虽然65,535是标准规定的最小值,但是一个非常小的设备可以指定标准故意因此而离开。

实际上,在一台大型机器上,早在实际耗尽内存之前,就会不必要地以一种会影响性能的方式对内存施加压力。 最好动态调整数组大小到合适的大小。