微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

功能中的旧尺寸无效

如何解决功能中的旧尺寸无效

所以我有功能

void getInput(char* input) {
        char buffer[BUFF_SIZE];
        char *buff = buffer;
        size_t buffersize = 32;
        getline(&buff,&buffersize,stdin);
        buffer[strlen(buffer) - 1] = '\0';
        strcpy(input,buffer);
}

,此函数将传递一个带有声明char input[BUFF_SIZE]的变量,并且BUFF_SIZE被定义为#define BUFF_SIZE 5000

无论如何,我遇到的错误是当我在gdb中调试它时出现错误 Error in './dash': realloc(): invalid old size: 0x00007ffdf5a6fab0 ***

在使用之后我将在何处获取此信息

#0  0x00002aaaaad05387 in raise () from /lib64/libc.so.6
#1  0x00002aaaaad06a78 in abort () from /lib64/libc.so.6
#2  0x00002aaaaad47ed7 in __libc_message () from /lib64/libc.so.6
#3  0x00002aaaaad4e3e4 in malloc_printerr () from /lib64/libc.so.6
#4  0x00002aaaaad537d1 in _int_realloc () from /lib64/libc.so.6
#5  0x00002aaaaad55c52 in realloc_hook_ini () from /lib64/libc.so.6
#6  0x00002aaaaad3e96b in getdelim () from /lib64/libc.so.6
#7  0x0000000000400f05 in getInput (input=0x7fffffffbae0 "") at dash.c:104
#8  0x0000000000400bbe in main (argc=1,argv=0x7fffffffe308) at dash.c:50

我现在完全迷失了,任何帮助将不胜感激。

解决方法

getline()的指针(指向指针)参数必须可传递给free()getline()的POSIX规范说:

应用程序应确保*lineptr是可以传递给free()函数的有效参数。如果*n不为零,则应用程序应确保*lineptr指向大小至少为*n个字节的对象,或者为空指针。

您违反了该限制,因为无法将局部变量buffer传递给free()。一切都可能崩溃—尤其是因为您还担心缓冲区的大小,声称实际上只有5000字节长,所以缓冲区只有32字节长(因此,对于很短的输入行,必须重新分配)。

阅读规范-遵循制定的规则。

getInput()函数也不知道函数的input参数所指向的缓冲区的大小,但是它无条件地复制了读入input的所有内容缓冲。那是缓冲区溢出的秘诀。您的getInput()函数需要一个不同的签名,并且应该更像:

ssize_t getInput(size_t in_len,char input[in_len])
{
    char *buffer = NULL;
    size_t *buflen = 0;
    ssize_t nbytes;
    if ((nbytes = getline(&buffer,&buflen,stdin)) == -1)
    {
        free(buffer);  // Free any space allocated by getline()
        return EOF;
    }
    if (buffer[nbytes - 1] == '\n'). /* Zap newline if present */
        buffer[--nbytes] = '\0';
    if ((size_t)nbytes >= in_len)
    {
        free(buffer);  // Release space allocated by getline()
        *input = '\0';
        return 0;   // Or another value to indicate an error
    }
    strcpy(input,buffer);
    free(buffer);
    return nbytes;
}

这将告诉您输入缓冲区中有多少字节,避免了溢出。就像您的原始功能一样,它确实会复制数据-大概对您来说没问题。

请注意,getline()返回-1而不是EOF(尽管两者通常是相同的)。在检测到EOF之前,它可以(通常确实)为NULL缓冲区指针分配空间,因此即使没有数据,也必须释放它分配的缓冲区。有效的getline()实现永远不会返回0,它会返回-1或严格为正的值。

,

问题在于,您不能将尚未分配给malloc的缓冲区传递给getline

或者,在调用getline()之前,* lineptr可以包含一个指向malloc(3)分配的缓冲区的指针* n个字节。 如果缓冲区的大小不足以容纳该行,则getline()使用realloc(3)调整其大小,并根据需要更新* lineptr和* n。

getline认为缓冲区不够大,因为传递的大小为32,所以它前进到realloc并失败,因为当系统在非(m )分配的realloc会调用未定义的行为(可能会使您的应用程序崩溃)。

如果设置了buffer,该错误将被隐藏,因为size_t buffersize = 5000;不必重新分配缓冲区(但是如果行大于5000个字符,这仍然很糟糕,所以它是还是一个错误)

因此,您必须将getline设置为buffer,并让NULL为您分配它。

getline

最后,用char *buff = NULL; size_t buffersize = 0; 取消分配

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。