为什么有一个 Invalid read of size 4

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

出现 Invalid read of size 4,但我不知道如何避免: 这是 valgrind 告诉我读取无效的地方

Queue* recordQueue = newQueue(NULL, NULL);
    
    FILE* file = fopen(fileName, "r");
    char* processName = malloc(8 * sizeof(char));
    assert(processName != NULL);
    unsigned int arriveTime;
    unsigned int serviceTime;
    short memoryRequirement;
    while (fscanf(file, "%d %s %d %hd", &arriveTime, processName, 
        &serviceTime, &memoryRequirement) != EOF) {
        ProcessStatus status = NOT_READY;
        ProcessInfo* processInfo = newProcessInfo(processName, arriveTime, 
            serviceTime, memoryRequirement, status);
        
        processName = malloc(8 * sizeof(char));
        assert(processName != NULL);
        inQueue(recordQueue, newNode(processInfo, NULL, NULL));
    }
    return recordQueue;

valgrind 表明:

==237688== Invalid read of size 4
==237688==    at 0x48C3AF2: __vfscanf_internal (vfscanf-internal.c:345)
==237688==    by 0x48C329C: __isoc99_fscanf (isoc99_fscanf.c:30)
==237688==    by 0x10A3AE: readProcessesFronFile (in /home/haozhec/project1/comp30023-2023-project-1/allocate)
==237688==    by 0x10A91D: main (in /home/haozhec/project1/comp30023-2023-project-1/allocate)
==237688==  Address 0xc0 is not stack'd, malloc'd or (recently) free'd
==237688== 
==237688== 
==237688== Process terminating with default action of signal 11 (SIGSEGV)
==237688==  Access not within mapped region at address 0xC0
==237688==    at 0x48C3AF2: __vfscanf_internal (vfscanf-internal.c:345)
==237688==    by 0x48C329C: __isoc99_fscanf (isoc99_fscanf.c:30)
==237688==    by 0x10A3AE: readProcessesFronFile (in /home/haozhec/project1/comp30023-2023-project-1/allocate)
==237688==    by 0x10A91D: main (in /home/haozhec/project1/comp30023-2023-project-1/allocate)

有人知道怎么解决吗? 谁能告诉我如何在使用 fscanf 时避免此类问题?

c valgrind
1个回答
2
投票

例如,如果文件不存在,

fopen
将返回一个空指针 -
fscanf
然后将尝试从
file
指向的内存中读取,但由于它是一个空指针,因此那里没有内存 - 那是无效读取。这就是 SIGSEGV 的原因(实际上是发生 segmentation fault 时发出的信号的名称)。

为了防止此类崩溃(并向用户反馈为什么您的程序没有按照用户期望的方式执行),您应该在使用

file
指针进行任何操作之前先检查空指针 - 所以,在
fopen 
行添加

if (!file) {
    fprintf(stderr, "Failed opening file '%s': %s\n",
            fileName, strerror(errno));
    return 0;
}

由于

file
是一个指针(无符号整数),如果指针地址不为零,它将在布尔运算符中计算为
true
。相反,如果指针等于
0
(因此是一个空指针),它的计算结果为
false
-
!
反转布尔结果,因此只要指针
file
等于
0
if
语句将是执行,提醒用户情况。

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