Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在什么情况下fscanf会溢出内存?_C_Linked List - Fatal编程技术网

在什么情况下fscanf会溢出内存?

在什么情况下fscanf会溢出内存?,c,linked-list,C,Linked List,我实现了一个链表,可以很好地处理各种文件输入(逐行读取并插入它们) 鉴于这段代码,我看到了一些问题,在读取“fff”之后,当使用给定的示例输入执行fscanf时,事情似乎变得糟糕 one two three ee fff ee 在分析ee时: list = 0x009dfac0 {name=0x009dfac0 "one" next=0x00c98c08 {name=0x00c98c08 "three" next=0x00c98ba0 {name=0x00c98ba0 "two" ...}

我实现了一个链表,可以很好地处理各种文件输入(逐行读取并插入它们)

鉴于这段代码,我看到了一些问题,在读取“fff”之后,当使用给定的示例输入执行fscanf时,事情似乎变得糟糕

one
two

three ee
fff
ee
在分析ee时:

list = 0x009dfac0 {name=0x009dfac0 "one" next=0x00c98c08 {name=0x00c98c08 "three" next=0x00c98ba0 {name=0x00c98ba0 "two" ...} } }
在下一个令牌之后:

list = 0x009dfac0 {name=0x009dfac0 "ee" next=0x009df068 {name=0x009df068 "È”ü\xf\x1" next=0x0ff7caa0 {msvcr110d.dll!_except_handler4(_EXCEPTION_RECORD *, _EXCEPTION_REGISTRATION_RECORD *, _CONTEXT *, void *)} {...} } 
在检查我的列表时,“下一个”指针在fscanf被触发后立即损坏。潜在的原因是什么

根据请求插入排序:

void insert_sorted(node_type* list, char* value)
{
    // Copy our pointer so we can move around
    node_type *n = (node_type*) malloc(sizeof *n); 
    node_type *loc = NULL;
    node_type *tmp;
    node_type dat;
    node_type* prev = list;
    node_type* head = list;

    n->next = NULL;
    strcpy(n->name, value); 

    // First element, assign immediately
    if( strcmp(list->name, "") == 0 )
    {
        *list = *n;
        return;
    }


    while(head != NULL)
    {
        // We should do a comparison to see if one is greater than another
        int cmp_result = strcmp(value, head->name);

        // If the value is bigger, this means the value needs to be inserted after
        if(cmp_result > 0)
        {           
            loc = head;
        }

        else if (cmp_result < 0) // this needs to be ahead
        {

            if(prev == head)    
            {
                dat = *head;
                *head = *n;
                head->next = &dat;
                return;
            }

            prev->next = n;
            n->next = head;
            return;
        }

        else if(cmp_result == 0)
        {
            free(n);
            return; // duplicate, die
        }


        // Advance to the next pointer
        prev = head;
        head = head->next;
    }


    // You've reached the end, that must mean you've succesfully reached the point to insert

    tmp = loc->next; // get the value we're going to end up detaching
    n->next = tmp; // link the two together
    loc->next = n;

}
void insert\u排序(节点类型*列表,字符*值)
{
//复制我们的指针,以便我们可以四处移动
node_type*n=(node_type*)malloc(sizeof*n);
节点类型*loc=NULL;
节点类型*tmp;
节点类型dat;
节点类型*prev=列表;
节点类型*头=列表;
n->next=NULL;
strcpy(n->名称、值);
//第一个元素,立即赋值
如果(strcmp(列表->名称“”)==0)
{
*列表=*n;
返回;
}
while(head!=NULL)
{
//我们应该做一个比较,看一个比另一个大
int cmp_result=strcmp(值,头->名称);
//如果该值较大,则意味着需要在后面插入该值
如果(cmp_结果>0)
{           
loc=水头;
}
else if(cmp_result<0)//这需要提前完成
{
如果(上一个==头部)
{
dat=*头;
*水头=*n;
head->next=&dat;
返回;
}
上一个->下一个=n;
n->next=头部;
返回;
}
else if(cmp_结果==0)
{
自由(n);
return;//复制,死亡
}
//前进到下一个指针
prev=头部;
头部=头部->下一步;
}
//您已到达终点,这一定意味着您已成功到达插入点
tmp=loc->next;//获取我们最终要分离的值
n->next=tmp;//将两者链接在一起
loc->next=n;
}
将循环修改为

while (fscanf(file, "%s", buffer) == 1) {
    length = strlen(buffer);
    // ...
}
因为
feof(file)
在最后一次成功
fscanf()之后仍然返回
0
。在第一次失败的
fscanf()
之后,它返回非0

关于
insert\u sorted()
,请查看以下几行:

            head->next = &dat;
            return;
由于
dat
是一个本地对象,一旦函数返回,保存其地址将导致地址无效。

将循环修改为

while (fscanf(file, "%s", buffer) == 1) {
    length = strlen(buffer);
    // ...
}
因为
feof(file)
在最后一次成功
fscanf()之后仍然返回
0
。在第一次失败的
fscanf()
之后,它返回非0

关于
insert\u sorted()
,请查看以下几行:

            head->next = &dat;
            return;
由于
dat
是一个本地对象,一旦函数返回,保存其地址将导致地址无效。

将循环修改为

while (fscanf(file, "%s", buffer) == 1) {
    length = strlen(buffer);
    // ...
}
因为
feof(file)
在最后一次成功
fscanf()之后仍然返回
0
。在第一次失败的
fscanf()
之后,它返回非0

关于
insert\u sorted()
,请查看以下几行:

            head->next = &dat;
            return;
由于
dat
是一个本地对象,一旦函数返回,保存其地址将导致地址无效。

将循环修改为

while (fscanf(file, "%s", buffer) == 1) {
    length = strlen(buffer);
    // ...
}
因为
feof(file)
在最后一次成功
fscanf()之后仍然返回
0
。在第一次失败的
fscanf()
之后,它返回非0

关于
insert\u sorted()
,请查看以下几行:

            head->next = &dat;
            return;

由于
dat
是一个本地对象,一旦函数返回,保存其地址将导致地址无效。

您没有正确测试文件结尾。通常,使用feof是不正确的,而是测试从文件中读取的函数的返回值

fscanf返回它能够读取的实体数。因此,在您的示例中,您将测试它是否返回1,这表示读取成功。为了避免缓冲区溢出,您可以对要读取的字符数设置一个限制,该限制的数字介于%和s之间

没有理由对缓冲区大小如此吝啬

因此:

顺便说一句,您阅读的不是“逐行”,而是“按空格分隔的字符串逐空格分隔的字符串”。要逐行读取文件,可以使用fgets


在你说“这不是问题”之前,先试试看。这些是此函数可能产生的唯一问题。

您没有正确测试文件结尾。通常,使用feof是不正确的,而是测试从文件中读取的函数的返回值

fscanf返回它能够读取的实体数。因此,在您的示例中,您将测试它是否返回1,这表示读取成功。为了避免缓冲区溢出,您可以对要读取的字符数设置一个限制,该限制的数字介于%和s之间

没有理由对缓冲区大小如此吝啬

因此:

顺便说一句,您阅读的不是“逐行”,而是“按空格分隔的字符串逐空格分隔的字符串”。要逐行读取文件,可以使用fgets


在你说“这不是问题”之前,先试试看。这些是此函数可能产生的唯一问题。

您没有正确测试文件结尾。通常,使用feof是不正确的,而是测试从文件中读取的函数的返回值

fscanf返回它能够读取的实体数。因此,在您的示例中,您将测试它是否返回1,这表示读取成功。为了避免缓冲区溢出,您可以对要读取的字符数设置一个限制,该限制的数字介于%和s之间

没有理由对缓冲区大小如此吝啬

因此:

顺便说一句,您读的不是“逐行”,而是“按空格分隔的字符串”