首页 > 解决方案 > C. 使用的内存多于 malloc 中分配的内存 - 我可以返回某事,结束程序而不是让它崩溃吗?

问题描述

malloc(x*sizeof(char))我的程序在, x< 限制时崩溃fgets,尽管buffer == NULL检查。

在我的示例中,当 x 为 1 时,fgets 可以采用的限制为 100,并且用户类型为例如。来自键盘的 5 个字符(fgets() 调用),程序崩溃,返回一些随机值,例如:19284791298 值。

我的问题:如果它返回NULL,我宁愿不要崩溃。

原因:我将代码上传到我的大学的 linux 平台,该平台测试程序对堆限制更改为 0 和 130 的反应,当我的程序被编写为在用户输入超过 100 个字符时返回 NULL 时。我不太明白环境如何将内存限制更改为 0 和 130 以及究竟发生了什么变化,但尽管如此,我注意到我在 CodeBlocks、Windows 10 中的程序在此处描述的这种情况下崩溃(x < stdin 输入)尽管检查buffer == NULL.

我希望buffer == NULL检查能以某种方式工作并防止崩溃。

如果x是 100,并且size是 1(而不是 1 和 100),我的程序将返回 NULL 并将 err_code 设置为 1。

我在想:我不能用 x 做与 strlen(buffer) 相同的“if”语句,因为...要检查写入缓冲区的输入有多长,首先我需要检查什么的长度已写入此缓冲区?!。

printf("Insert data: ");
char *buffer = (char* )malloc(1*sizeof(char));
if (buffer == NULL) 
    return NULL;

int size=100;
if (fgets(buffer, size, stdin)!=NULL) {
    if (strlen(buffer)>(unsigned)(size-2)) { //'\0' and enter are 2 chars
        free(buffer);
        *err_code=1;
        return NULL;
    }
//... here goes some sscanf to fill struct fields, etc.
}

换句话说。稍微浓缩一下我认为可能会导致对我的问题的理解:

  1. 有没有办法结束程序返回一些东西,而不是让它在这种情况下崩溃?一种if(buffer == NULL)工作方式?为什么这个检查不起作用?

  2. 我对linux不熟悉。当我在收到的报告中看到一条评论时,linux 将(堆?)限制设置为 0 或 130(在测试我的程序时),这是否意味着我可以通过将 my 设置为来复制遇到x0问题130?(在部分malloc(x*sizeof(char)).

标签: cmallocstdin

解决方案


当您调用时,您必须告诉它目标缓冲区fgets多大。您不只是告诉它您希望它读取的最大字符数,以便它可以自动分配那么多空间,或者类似的东西。您告诉它缓冲区的大小已经是多少,并且您告诉它绝对不能读取更多字符,否则缓冲区将溢出。(从不自己进行任何分配。)fgetsfgets

所以当你说

char *buffer = (char* )malloc(1*sizeof(char));

其次是

int size=100;
fgets(buffer, size, stdin)

你撒谎了。您分配了一个大小为 1 的缓冲区,并且您告诉fgets缓冲区大小为 100。因此fgets将读取最多 99 个字符,并将它们存储到buf中,并且在大多数情况下,这将严重溢出缓冲区。

你想要做的是更像这样的事情:

int size = 100;
char *buffer = (char* )malloc(size*sizeof(char));
if (buffer == NULL) 
    return NULL;

if (fgets(buffer, size, stdin)!=NULL) {
    ...

此外,虽然它与您的问题没有任何关系,但sizeof(char)调用时不需要乘以malloc,并且在 C 中,也不需要将 return frommalloc转换为目标指针类型。我只想打电话

char *buffer = malloc(size);

推荐阅读