出现 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 时避免此类问题?
例如,如果文件不存在,
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
语句将是执行,提醒用户情况。