繁体   English   中英

以C为单位的最大数组大小

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM