打开的文件太多 c

Posted

技术标签:

【中文标题】打开的文件太多 c【英文标题】:too many open files c 【发布时间】:2014-07-09 13:45:16 【问题描述】:

我一直在尝试创建一个简单的程序。但是,我遇到了一个错误:

gmon.out:打开的文件太多

我不清楚为什么它说我“打开的文件太多”。我似乎没有使用文件。

#include<stdio.h>
#include<ctype.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>

struct position

    int line;
    int place;
    struct position *next;
;
struct file

    struct position *info;
    struct file *next;
    char *name;
;
struct word

    char *name;
    struct word *right;
    struct word *left;
    struct file *result;
;

int main()

    int i;
    struct word *d,*c;
    char *s="brutus";
    printf("%s",s);
    c=(struct word*)malloc(sizeof(struct word));
    strcpy(c->name,s);
    c->left=NULL;
    c->right=NULL;
    for(i=1;i<=10;i++)
    
        d=(struct word*)malloc(sizeof(struct word));
        if(d==NULL)
            exit(0);

        scanf("%s",s);
        printf("4");
        s=d->name;

        printf("%s",d->name);

        d->left=NULL;
        d->right=NULL;
    
    system("pause");
    exit(0);

我该怎么办?提前感谢您的宝贵时间!

【问题讨论】:

没有分配s ...调用scanf时内存将被破坏。 @Al.Sal 请看这篇帖子meta.stackexchange.com/questions/15650/… 我完全不介意人们是否会转换 malloc 的返回值。 C++ 开发人员一直都在这样做,所以我想听听一个很好的理由,假设它有一个不错的开发系统。 @user3697730: char *s 实际上是const char *s,因为你已经分配了一个字符串字面量:该字符串存储在只读内存中 @user3697730:请通读本网站的帮助部分:请您不要离开“谢谢” cmets。而是将最能帮助您的答案标记为已接受。我已将我所有的 cmets + 更多详细信息捆绑到一个答案中,因为这些 cmets 只解决了您遇到的一半问题 【参考方案1】:

首先:

gmon.out:打开的文件太多

表示您正在使用-p 标志(分析)进行编译。 gmon.out 是 gprof 使用的默认文件名。只需放弃开关,您就不会再遇到这个问题了。 当然,不分析代码并不好,但您最好先解决一些问题,然后再开始实际分析您的代码。

其中一些,相当多的问题是:

char *s="brutus";
printf("%s",s);
c=(struct word*)malloc(sizeof(struct word));
strcpy(c->name,s);

问题列表:

char *s 应该是const char *s,因为它指向只读内存。 接下来,Do not cast the return of malloc 检查像malloc 这样的函数的返回值,它们会告诉你一些事情 struct word是一个所有成员都是指针的结构。分配结构后,这些指针无效:您也需要为这些成员分配内存 strcpy 期望目标 (c-&gt;name) 是一个有效的指针,正如我上面解释的:这里不是这种情况

那么,这段代码应该是什么样子:

const char *s = "brutus";
c = malloc(sizeof *c);
if (c == NULL)

    fprintf(stderr, "Could not allocate memory for struct word\n");
    exit( EXIT_FAILURE );

//allocate enough memory to store the string
c->name = malloc(
    (strlen(s)+1) * sizeof *c->name
);
//OR same, but shorter, works because the type char is guaranteed by the standard to be 1 byte in size
c->name = malloc(strlen(s)+1);
if (c->name == NULL)
    exit( EXIT_FAILURE );//could not allocate mem
c->name[0] = '\0';//set to empty string, now we can use safer functions:
strncat(c->name, s, strlen(s));

在你解决了这些问题之后,认真地重新考虑你的方法,并问问自己你在这里真正想要做什么:

for(i=1;i<=10;i++)

    d=(struct word*)malloc(sizeof(struct word));
    if(d==NULL)
        exit(0);

    scanf("%s",s);
    printf("4");
    s=d->name;

您分配了 10 次结构,每次都将其重新分配给 d。但是,您永远不会释放此内存。这是不好的做法。 再说一遍:不要返回 malloc,但这是你最不担心的。

if (d == NULL)
    exit(0);

好的,现在你检查malloc 的返回。伟大的。但是你到底为什么要以 0 结束(表示成功运行)。这也有一个宏。你可以这样写:

if (d == NULL)
    exit( EXIT_SUCCESS);

显然,EXIT_SUCCESS 不是您应该交流的对象。const char *s 现在用于存储用户输入。但是,这行不通,因为它指向 只读 内存,所以忘记不安全的scanf("%s", s); 语句。使用堆栈变量,并确保输入缓冲区已被清除,或者使用安全的替代方法。 但后来你去做了像这样荒谬的事情:

s = d->name;

同样,d-&gt;namec 的情况一样,是一个无效指针。为什么在这里分配给s?没有意义,没有理由……只有疯狂。

底线:在它孵化之前杀死这段代码,重新开始,请使用这些提示/建议和批评作为指导。

【讨论】:

【参考方案2】:

我不知道您为什么会收到“打开的文件太多”,但是这一行:

strcpy(c->name,s)

正在将数据写入随机内存,这可能会导致各种问题。 你需要先 malloc() 那个 c->name。

另外,scanf to s 看起来很可疑,并且 d->name 也从未分配任何东西。

您收到“打开的文件过多”的原因可能是因为某些内存以恰好触发特定错误的方式被覆盖。欢迎来到未定义行为的世界。 IE:如果你覆盖随机内存,基本上任何事情都可能发生。

【讨论】:

【参考方案3】:

第一个bug就在一行

    strcpy(c->name,s);

此时,c->name 是一个未初始化的指针,所以如果幸运的话程序会崩溃。

阅读您的评论:您修复了第二个错误。第一个错误仍未修复。还有第三个错误

    s=d->name;

【讨论】:

【参考方案4】:

这个字符串副本将在内存中运行,从 c->name 指向的任何位置开始,直到找到一个空终止符。

strcpy(c->name,s);

您已经为 c 分配了空间,但没有为 c 中的名称指针分配空间。

c->name = malloc([某个长度]);

c->name 指向某个地方,但在 malloc 之前你不知道在哪里。这就是为什么你会得到一个看似随机的错误,因为你从一个未知的位置执行一个未知数量的字节的字符串副本,并且你正在破坏任何 s 指向的未知数量的字节。

【讨论】:

以上是关于打开的文件太多 c的主要内容,如果未能解决你的问题,请参考以下文章

C++ 管道,打开的文件太多,Errno 25

延迟打开的文件导致“打开的文件太多”

无法打开设备:打开的文件太多错误

一打开文件夹就卡死

无法打开链接描述文件 libgcc_s.so.1:打开的文件太多

grails 应用程序中的“打开的文件太多” - 如何正确关闭打开的文件和流?