从 stdin 获取输入的问题 - 来自 valgrind 的 read/write 无效
Problems with taking input from stdin - Invalid read/write from valgrind
我 运行 在我正在处理的程序上使用 valgrind,我收到以下错误 - 我不明白为什么。任何帮助将不胜感激提前。如果您需要更多信息,请告诉我
==27928== Invalid read of size 1
==27928== at 0x4EB9390: __GI___rawmemchr (rawmemchr.S:25)
==27928== by 0x4EA514F: _IO_str_init_static_internal (strops.c:45)
==27928== by 0x4E86D64: __isoc99_vsscanf (isoc99_vsscanf.c:42)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4C2B834: __GI___rawmemchr (mc_replace_strmem.c:1110)
==27928== by 0x4EA514F: _IO_str_init_static_internal (strops.c:45)
==27928== by 0x4E86D64: __isoc99_vsscanf (isoc99_vsscanf.c:42)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb041 is 1 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4E7D920: _IO_vfscanf (vfscanf.c:620)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4EA36D2: _IO_sputbackc (genops.c:731)
==27928== by 0x4E7D97B: _IO_vfscanf (vfscanf.c:625)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4E7DC7D: _IO_vfscanf (vfscanf.c:1394)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4E7E9EF: _IO_vfscanf (vfscanf.c:1781)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb041 is 1 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4EA36D2: _IO_sputbackc (genops.c:731)
==27928== by 0x4E7DDF3: _IO_vfscanf (vfscanf.c:1811)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb041 is 1 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
不管您对每个错误的起源有何看法,通过大量的反复试验,在代码块中注释 out/back 并在测试编译中单独测试代码片段,我发现以下是错误的来源。如果我在我的程序中注释掉这段代码,所有错误都会消失。
注意:整数是全局 int* 类型。 countToUse 是全局 int 类型。此处代码的目标是从 stdin 中读取所有整数并将它们放入大小正确的动态数组中。
// Load stdin into a buffer
char *buffer = malloc(BUFFER_SIZE);
if(buffer == NULL){
fprintf(stderr, "Malloc for stdin buffer in countAndSort() failed. Exiting.\n");
exit(1);
}
if (fgets(buffer, BUFFER_SIZE, stdin) == NULL) {
fprintf(stderr, "Error loading input from stdin into buffer. Exiting.\n");
exit(1);
}
// Get a count of the numbers to create the array
int count = 0;
int index = 0;
int num, delta;
while (index < BUFFER_SIZE && sscanf(&buffer[index], "%d%n", &num, &delta) == 1){
count++;
index += delta;
}
// Initialize the array with the proper size
integers = malloc(count*sizeof(int));
if(integers == NULL){
fprintf(stderr, "Malloc for integer array in countAndSort() failed. Exiting. \n");
exit(1);
}
// Load the integers into the array
index = 0;
for (int i = 0; i < count; i++){
// LINE 442 IS RIGHT BELOW THIS LINE ------------------------------------
if (index < BUFFER_SIZE && sscanf(&buffer[index], "%d%n", &integers[i], &delta) != 1){
fprintf(stderr, "There was a problem reading the buffer!\n");
exit(1);
}
index += delta;
}
if(buffer != NULL)
free(buffer);
countToUse = count;
你需要确保你的阅读没有超出 buffer
的范围,像这样
while ((index < 10000000) && (sscanf(&buffer[index], "%d%n", &num, &delta) == 1))
这同样适用于所有 buffer[index]
。
此外,从错误来看,您似乎有 free()
d buffer
然后尝试从中读取。
我 运行 在我正在处理的程序上使用 valgrind,我收到以下错误 - 我不明白为什么。任何帮助将不胜感激提前。如果您需要更多信息,请告诉我
==27928== Invalid read of size 1
==27928== at 0x4EB9390: __GI___rawmemchr (rawmemchr.S:25)
==27928== by 0x4EA514F: _IO_str_init_static_internal (strops.c:45)
==27928== by 0x4E86D64: __isoc99_vsscanf (isoc99_vsscanf.c:42)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4C2B834: __GI___rawmemchr (mc_replace_strmem.c:1110)
==27928== by 0x4EA514F: _IO_str_init_static_internal (strops.c:45)
==27928== by 0x4E86D64: __isoc99_vsscanf (isoc99_vsscanf.c:42)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb041 is 1 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4E7D920: _IO_vfscanf (vfscanf.c:620)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4EA36D2: _IO_sputbackc (genops.c:731)
==27928== by 0x4E7D97B: _IO_vfscanf (vfscanf.c:625)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4E7DC7D: _IO_vfscanf (vfscanf.c:1394)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4E7E9EF: _IO_vfscanf (vfscanf.c:1781)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb041 is 1 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928== at 0x4EA36D2: _IO_sputbackc (genops.c:731)
==27928== by 0x4E7DDF3: _IO_vfscanf (vfscanf.c:1811)
==27928== by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928== by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928== by 0x401A76: countAndSort (lab1.c:442)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928== Address 0x55bb041 is 1 bytes inside a block of size 10,000,000 free'd
==27928== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928== by 0x4019D6: countAndSort (lab1.c:430)
==27928== by 0x4014EB: doProcess (lab1.c:316)
==27928== by 0x4011C2: main (lab1.c:211)
==27928==
不管您对每个错误的起源有何看法,通过大量的反复试验,在代码块中注释 out/back 并在测试编译中单独测试代码片段,我发现以下是错误的来源。如果我在我的程序中注释掉这段代码,所有错误都会消失。
注意:整数是全局 int* 类型。 countToUse 是全局 int 类型。此处代码的目标是从 stdin 中读取所有整数并将它们放入大小正确的动态数组中。
// Load stdin into a buffer
char *buffer = malloc(BUFFER_SIZE);
if(buffer == NULL){
fprintf(stderr, "Malloc for stdin buffer in countAndSort() failed. Exiting.\n");
exit(1);
}
if (fgets(buffer, BUFFER_SIZE, stdin) == NULL) {
fprintf(stderr, "Error loading input from stdin into buffer. Exiting.\n");
exit(1);
}
// Get a count of the numbers to create the array
int count = 0;
int index = 0;
int num, delta;
while (index < BUFFER_SIZE && sscanf(&buffer[index], "%d%n", &num, &delta) == 1){
count++;
index += delta;
}
// Initialize the array with the proper size
integers = malloc(count*sizeof(int));
if(integers == NULL){
fprintf(stderr, "Malloc for integer array in countAndSort() failed. Exiting. \n");
exit(1);
}
// Load the integers into the array
index = 0;
for (int i = 0; i < count; i++){
// LINE 442 IS RIGHT BELOW THIS LINE ------------------------------------
if (index < BUFFER_SIZE && sscanf(&buffer[index], "%d%n", &integers[i], &delta) != 1){
fprintf(stderr, "There was a problem reading the buffer!\n");
exit(1);
}
index += delta;
}
if(buffer != NULL)
free(buffer);
countToUse = count;
你需要确保你的阅读没有超出 buffer
的范围,像这样
while ((index < 10000000) && (sscanf(&buffer[index], "%d%n", &num, &delta) == 1))
这同样适用于所有 buffer[index]
。
此外,从错误来看,您似乎有 free()
d buffer
然后尝试从中读取。