C.使用比 malloc 中分配的内存更多的内存 - 我可以返回某物,结束程序而不是让它崩溃吗?

问题描述 投票:0回答:2

尽管进行了

malloc(x*sizeof(char))
检查,但当
x
、< limit of
fgets
buffer == NULL
时,我的程序崩溃了。

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

我的问题:我宁愿它返回 NULL,而不是崩溃。

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

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(测试我的程序时),这是否意味着我可以通过将我的

    x
    设置为
    0
    来复制它遇到的问题,
    130
    ? (在
    malloc(x*sizeof(char))
    部分。

c malloc stdin
2个回答
4
投票

当你调用

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

所以当你说

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
(因为
sizeof(char)
按照定义就是1),而且在C中也不需要将 
malloc
 的返回值转换为目标指针类型。  我就打电话

char *buffer = malloc(size);
    

1
投票
在您的代码中,您已将缓冲区分配为单字节数组

char *buffer = (char* )malloc(1*sizeof(char)); int size=100; if (fgets(buffer, size, stdin)!=NULL) {

在 fget 中,您需要将 100 个字节的输入读入缓冲区。当输入读入缓冲区时,它超出了分配的区域并覆盖其他数据。因此,你的程序崩溃了,

© www.soinside.com 2019 - 2024. All rights reserved.