[英]Maximum Array Size in C
我编写了一个程序来读取文本文件,将所有文件内容发送到消息队列,然后在控制台中显示。 我拥有的文本文件的大小从30kb到30mb不等。 现在,我的程序最多只能读取1024个字节。 为了读取所有文件内容,我应该将MAX设置为多少? 还是其他地方存在问题? 请指教。 非常感谢您的帮助。
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define MAX 1024 //1096
//Declare the message structure
struct msgbuf
{
long type;
char mtext[MAX];
};
//Main Function
int main (int argc, char **argv)
{
key_t key; //key to be passed to msgget()
int msgid; //return value from msgget()
int len;
struct msgbuf *mesg; //*mesg or mesg?
int msgflg = 0666 | IPC_CREAT;
int fd;
char buff[MAX];
//Initialize a message queue
//Get the message queue id
key = ftok("test.c", 1);
if (key == -1)
{
perror("Can't create ftok.");
exit(1);
}
msgid = msgget(key, msgflg);
if (msgid < 0)
{
perror("Cant create message queue");
exit(1);
}
//writer
//send to the queue
mesg=(struct msgbuf*)malloc((unsigned)sizeof(struct msgbuf));
if (mesg == NULL)
{
perror("Could not allocate message buffer.");
exit(1);
}
//set up type
mesg->type = 100;
//open file
fd = open(argv[1], O_RDONLY);
while (read(fd,buff,sizeof(buff))>0)
{
//printf("%s\n", buff);
strcpy(mesg->mtext,buff);
}
if(msgsnd(msgid, mesg, sizeof(mesg->mtext), IPC_NOWAIT) == -1)
{
perror("Cant write to message queue");
exit(1);
}
//reader
int n;
while ((n=msgrcv(msgid, mesg, sizeof(mesg->mtext), 100, IPC_NOWAIT)) > 0)
{
write(1, mesg->mtext, n);
printf("\n");
}
//delete the message queue
msgctl(msgid,IPC_RMID,NULL);
close(fd);
}
如果要使用缓冲区,则想法是选择代表您要处理的最有意义的数据量的最小大小。 读取要构建的体系结构的字长块的倍数很常见。
但是请记住,读取大量字节并将其存储在堆栈中是非常糟糕的。 这将很容易导致堆栈溢出。 如果必须将其存储在内存中,则最大的空间将是内存池。 有一些解决方法:一次处理大量的字节(而不是整个文件)。 这就是动态数组或其他ADT的想法发挥作用的地方。
对于您的特定情况“ 读取文件并将其输出到控制台 ”,实际上比您想象的要容易得多。 您一次只能读取一个字节,直到EOF
并将其输出到stdout
。 无需队列或任何东西。
编辑:根据您的请求,我建议的解决方案的一个示例:
for ( int byte = getchar(); byte != EOF; byte = getchar() ) {
printf( "%c", byte );
}
...就是这样。 一次只处理一个字节。 然后,您可以将文本文件通过管道传输到程序:
./program < textfile.txt
一次将一个大(数兆字节)的文件读到一个已分配堆栈的缓冲区中是一个坏主意,因为如果缓冲区超过堆栈大小,您将得到堆栈溢出。 我相信默认堆栈大小在Windows上为1 MB,在Linux上为8 MB。 (这取决于编译器吗?)
此外,堆栈数组的大小是固定的(无论如何都在C89中),因此您必须猜测最大的文件可能有多大,然后分配足够大的缓冲区来容纳该文件,这可能非常浪费。
如果出于某种原因一次需要将文件全部保存在内存中,则需要使用malloc()
对缓冲区进行堆分配。 但是,最好一次在固定大小的缓冲区中处理文件的小块。 这将使您能够安全地在堆栈上分配缓冲区,并且内存效率更高。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.