PSET4恢复分段故障 [英] PSET4 recover segmentation fault
问题描述
在这段代码中,我想从一个文件中写出50个JPG。
(实际说明:) [ ^ ]
In this code, I want to write out 50 JPGs from a file.
(actual instructions: )[^]
This is the terminal output:
~/workspace/pset4/jpg/ $ make recover clang -fsanitize=integer -fsanitize=undefined -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wshadow recover.c -lcrypt -lcs50 -lm -o recover ~/workspace/pset4/jpg/ $ ./recover
---Segmentation fault---
With valgrind, I see that there are no leaks, but a line says that no memory allocations were made:
Invalid read of size 4 ==17227== at 0x5E268D4: fclose@@GLIBC_2.2.5 (iofclose.c:54) ==17227== by 0x42DB5F: main (recover.c:85)
==17227== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==17227==
==17227==
==17227== Process terminating with default action of signal 11 (SIGSEGV)
==17227== Access not within mapped region at address 0x0
==17227== at 0x5E268D4: fclose@@GLIBC_2.2.5 (iofclose.c:54)
==17227== by 0x42DB5F: main (recover.c:85) ==17227== If you believe this happened as a result of a stack
==17227== overflow in your program's main thread (unlikely but
==17227== possible), you can try to increase the size of the
==17227== main thread stack using the --main-stacksize= flag.
==17227== The main thread stack size used in this run was 8388608.
==17227==
==17227== HEAP SUMMARY:
==17227== in use at exit: 0 bytes in 0 blocks
==17227== total heap usage: 1 allocs, 1 frees, 568 bytes allocated =
=17227==
==17227== All heap blocks were freed -- no leaks are possible
==17227==
==17227== For counts of detected and suppressed errors, rerun with: -v
==17227== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
Thanks a lot,
我尝试过:
What I have tried:
/**
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <stdint.h>
int main()
{
typedef uint8_t BYTEINBITS;
int pictcount = 0;
FILE* input = fopen("card.raw", "r");
if ( input == NULL )
{
printf(" Could not open card.raw \n");
return 2;
}
FILE* output = NULL;
bool atend = false;
while ( atend == false)
{
BYTEINBITS buffer[512];
fread( &buffer, 512 * sizeof(char), 1, input);
bool jpg = true;
if ( !( ( buffer[0] == 255 ) && ( buffer[1] == 216 ) && ( buffer[2] == 255) && ( buffer[3] > 224 ) ) )
{
jpg = false;
}
if (jpg == true)
{
if (pictcount >= 1)
{
fclose(output);
}
pictcount++;
char title[8];
sprintf(title,"%03d.jpg", pictcount);
output = fopen("title", "w");
}
if (pictcount > 0)
{
fwrite( &buffer, 512 * sizeof(char), 1, output );
}
if ( fread( &buffer, 512*sizeof(char), 1, input) != 1)
{
atend = true;
}
}
fclose(input);
fclose(output);
}
推荐答案
make recover clang -fsanitize =整数-fsanitize = undefined -ggdb3 -O0 -std = c11 -Wall -Werror -Wextra -Wno-sign-compare -Wshadow recover.c -lcrypt -lcs50 -lm -o recover~ / workspace / pset4 / jpg /
make recover clang -fsanitize=integer -fsanitize=undefined -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wshadow recover.c -lcrypt -lcs50 -lm -o recover ~/workspace/pset4/jpg/
./ recover
---分段错误---
使用valgrind,我看到没有泄漏,但是一行表示没有进行内存分配:
无效读取大小4 == 17227 ==在0x5E268D4:fclose @@ GLIBC_2.2.5(iofclose.c:54)== 17227 == by 0x42DB5F: main(recover.c:85)
== 17227 ==地址0x0没有堆叠,malloc'd或(最近)free'd
== 17227 ==
== 17227 ==
== 17227 ==使用信号11的默认操作终止进程(SIGSEGV)
== 17227 ==不在地址0x0 $ b的映射区域内访问$ b == 17227 ==在0x5E268D4:fclose @@ GLIBC_2.2.5(iofclose.c:54)
== 17227 == by 0x42DB5F:main(recover.c:85)== 17227 ==如果你认为这是因为你的程序的主线程中出现了堆栈
== 17227 ==溢出(不太可能但是
== 17227 ==可能),你可以尝试增加
== 17227 ==使用--main-stacksize =标志的主线程堆栈。
== 17227 ==此次运行中使用的主要线程堆栈大小为8388608.
== 17227 ==
== 17227 == HEAP SUMMARY:
== 17227 = =在退出时使用:0个块中的0个字节
== 17227 ==总堆使用量:1个分配,1个释放,568个字节分配=
= 17227 ==
== 17227 = =释放所有堆块 - 不可能发生泄漏
== 17227 ==
== 17227 ==对于检测到的和抑制的错误计数,请重新运行:-v
== 17227 ==错误摘要:来自1个上下文的1个错误(被抑制:0从0开始)
分段错误
非常感谢,
./recover ---Segmentation fault--- With valgrind, I see that there are no leaks, but a line says that no memory allocations were made: Invalid read of size 4 ==17227== at 0x5E268D4: fclose@@GLIBC_2.2.5 (iofclose.c:54) ==17227== by 0x42DB5F: main (recover.c:85) ==17227== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==17227== ==17227== ==17227== Process terminating with default action of signal 11 (SIGSEGV) ==17227== Access not within mapped region at address 0x0 ==17227== at 0x5E268D4: fclose@@GLIBC_2.2.5 (iofclose.c:54) ==17227== by 0x42DB5F: main (recover.c:85) ==17227== If you believe this happened as a result of a stack ==17227== overflow in your program's main thread (unlikely but ==17227== possible), you can try to increase the size of the ==17227== main thread stack using the --main-stacksize= flag. ==17227== The main thread stack size used in this run was 8388608. ==17227== ==17227== HEAP SUMMARY: ==17227== in use at exit: 0 bytes in 0 blocks ==17227== total heap usage: 1 allocs, 1 frees, 568 bytes allocated = =17227== ==17227== All heap blocks were freed -- no leaks are possible ==17227== ==17227== For counts of detected and suppressed errors, rerun with: -v ==17227== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Segmentation fault Thanks a lot,
我尝试过:
What I have tried:
/**
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <stdint.h>
int main()
{
typedef uint8_t BYTEINBITS;
int pictcount = 0;
FILE* input = fopen("card.raw", "r");
if ( input == NULL )
{
printf(" Could not open card.raw \n");
return 2;
}
FILE* output = NULL;
bool atend = false;
while ( atend == false)
{
BYTEINBITS buffer[512];
fread( &buffer, 512 * sizeof(char), 1, input);
bool jpg = true;
if ( !( ( buffer[0] == 255 ) && ( buffer[1] == 216 ) && ( buffer[2] == 255) && ( buffer[3] > 224 ) ) )
{
jpg = false;
}
if (jpg == true)
{
if (pictcount >= 1)
{
fclose(output);
}
pictcount++;
char title[8];
sprintf(title,"%03d.jpg", pictcount);
output = fopen("title", "w");
}
if (pictcount > 0)
{
fwrite( &buffer, 512 * sizeof(char), 1, output );
}
if ( fread( &buffer, 512*sizeof(char), 1, input) != 1)
{
atend = true;
}
}
fclose(input);
fclose(output);
}
错误在于:
The error is here:
BYTEINBITS buffer[512];
fread( &buffer, 512 * sizeof(char), 1, input);
buffer
是一个数组,因此已经是一个指针,但是你将该指针的地址传递给 fread
(你传递指针指针而不是指针)。
工作版应该如下: br />
buffer
is an array and therefore already a pointer but you are passing the address of that pointer to fread
(you are passing a pointer to a pointer instead of a pointer).
A working version should look like:
uint8_t buffer[512];
fread(buffer, sizeof(buffer), 1, input);
请注意,我还为 uint8_t $ c $删除了无用的
typedef
c>(它使代码的可读性降低),固定缓冲区大小为512, sizeof(char)
(可能与不一样)的sizeof(uint8_t)
)。只需使用 sizeof(缓冲区)
,它将扩展为以字节为单位的数组大小。
Note that I have also removed the useless typedef
for uint8_t
(it makes the code less readable), the fixed buffer size of 512 and the sizeof(char)
(which might not always the same as sizeof(uint8_t)
). Just use sizeof(buffer)
which expands to the array size in bytes.
这篇关于PSET4恢复分段故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!