打开的文件太多 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->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->name
与 c
的情况一样,是一个无效指针。为什么在这里分配给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的主要内容,如果未能解决你的问题,请参考以下文章