C语言 一个字符数组中可以有多少个字符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5351919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:06:00  来源:igfitidea点击:

How many chars can be in a char array?

carraysmemorycharbuffer

提问by user666010

#define HUGE_NUMBER ???

char string[HUGE_NUMBER];
do_something_with_the_string(string);

I was wondering what would be the maximum number that I could add to a char array without risking any potential memory problems, buffer overflows or the like. I wanted to get user input into it, and possibly the maximum possible.

我想知道在不冒任何潜在内存问题、缓冲区溢出等风险的情况下,我可以添加到字符数组的最大数量是多少。我想让用户输入它,并且可能是尽可能多的。

回答by Greg

See this response by Hyman Klein (see original post):

请参阅 Hyman Klein 的此回复(请参阅原始帖子):

The original C standard (ANSI 1989/ISO 1990) required that a compiler successfully translate at least one program containing at least one example of a set of environmental limits. One of those limits was being able to create an object of at least 32,767 bytes.

This minimum limit was raised in the 1999 update to the C standard to be at least 65,535 bytes.

No C implementation is required to provide for objects greater than that size, which means that they don't need to allow for an array of ints greater than (int)(65535 / sizeof(int)).

In very practical terms, on modern computers, it is not possible to say in advance how large an array can be created. It can depend on things like the amount of physical memory installed in the computer, the amount of virtual memory provided by the OS, the number of other tasks, drivers, and programs already running and how much memory that are using. So your program may be able to use more or less memory running today than it could use yesterday or it will be able to use tomorrow.

Many platforms place their strictest limits on automatic objects, that is those defined inside of a function without the use of the 'static' keyword. On some platforms you can create larger arrays if they are static or by dynamic allocation.

最初的 C 标准 (ANSI 1989/ISO 1990) 要求编译器成功翻译至少一个包含一组环境限制的至少一个示例的程序。这些限制之一是能够创建至少 32,767 字节的对象。

这个最小限制在 1999 年对 C 标准的更新中提高到至少 65,535 字节。

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

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

许多平台对自动对象设置了最严格的限制,即在函数内部定义的那些不使用“static”关键字的对象。在某些平台上,如果它们是静态的或通过动态分配,您可以创建更大的数组。

Now, to provide a slightly more tailored answer, DO NOT DECLARE HUGE ARRAYS TO AVOID BUFFER OVERFLOWS. That's close to the worst practice one can think of in C. Rather, spend some time writing good code, and carefully make sure that no buffer overflow will occur. Also, if you do not know the size of your array in advance, look at malloc, it might come in handy :P

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

回答by Bernd Elkemann

It depends on where char string[HUGE_NUMBER];is placed.

这取决于char string[HUGE_NUMBER];放置的位置。

  • Is it inside a function? Then the array will be on the stack, and ifand how fastyour OS can grow stacks depends on the OS. So here is the general rule: dont place huge arrays on the stack.

  • Is it ouside a function then it is global (process-memory), if the OS cannot allocate that much memory when it tries to load your program, your program will crash and your program will have no chance to notice that (so the following is better:)

  • Large arrays should be malloc'ed. With malloc, the OS will return a null-pointer if the mallocfailed, depending on the OS and its paging-scheme and memory-mapping-scheme this will either fail when 1) there is no continuous region of free memory large enough for the array or 2) the OS cannot map enough regions of free physical memory to memory that appears to your process as continous memory.

  • 它是在函数内部吗?那么阵列将在堆栈上,并且如果如何快速您的操作系统可以增长栈取决于操作系统。所以这里是一般规则:不要在堆栈上放置巨大的数组。

  • 它是否在函数之外,然后它是全局的(进程内存),如果操作系统在尝试加载您的程序时无法分配那么多内存,您的程序将崩溃并且您的程序将没有机会注意到(所以以下是更好的:)

  • 大型数组应该被malloc编辑。使用 malloc,如果malloc失败,操作系统将返回一个空指针,这取决于操作系统及其分页方案和内存映射方案,这将在 1) 没有足够大的连续可用内存区域用于数组时失败或 2) 操作系统无法将足够的空闲物理内存区域映射到在您的进程中显示为连续内存的内存。

So, with large arrays do this:

因此,对于大型数组,请执行以下操作:

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

回答by John Bode

Declaring arbitrarily huge arrays to avoid buffer overflows is bad practice. If you really don't know in advance how large a buffer needs to be, use mallocor reallocto dynamically allocate and extend the buffer as necessary, possibly using a smaller, fixed-sized buffer as an intermediary.

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

Example:

例子:

#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");

       }
     }
   }

回答by Jon

If the array is going to be allocated on the stack, then you are limited by the stack size (typically 1MB on Windows, some of it will be used so you have even less). Otherwise I imagine the limit would be quite large.

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

However, making the array really big is not a solution to buffer overflow issues. Don't do it. Use functions that have a mechanism for limiting the amount of buffer they use to make sure you don't overstep your buffer, and make the size something more reasonable (1K for example).

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

回答by vbence

You can use malloc()to get larger portions of memory than normally an array could handle.

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

回答by Jon Hanna

Well, a buffer overflow wouldn't be caused by too large a value for HUGE_NUMBER so much as too small compared to what was written to it (write to index HUGE_NUMBER or higher, and you've overflown the buffer).

嗯,缓冲区溢出不会由 HUGE_NUMBER 的值太大而导致与写入的值相比太小(写入索引 HUGE_NUMBER 或更高,并且您已经溢出缓冲区)。

Aside from that it will depend upon the machine. There are certainly systems that could handle several millions in the heap, and a million or so on the stack (depending on other pressures), but there are also certainly some that couldn't handle more than a few hundred (small embedded devices would be an obvious example). While 65,535 is a standard-specified minimum, a really small device could specify that the standard was deliberately departed from for this reason.

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

In real terms, on a large machine, long before you actually run out of memory, you are needlessly putting pressure on the memory in a way that would affect performance. You would be better off dynamically sizing an array to an appropriate size.

实际上,在大型机器上,早在您真正用完内存之前,您就会以一种会影响性能的方式对内存施加不必要的压力。您最好将数组动态调整为适当的大小。