读取文件并转换其字符的 C 程序会产生双重释放或损坏错误
Program in C who reads a file and transform his characters produces a double free or corruption error
当执行我的程序时,我有这个错误:
*** Error in `./xorcipher': double free or corruption (!prev): 0x00000000024a1010 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fe869b317e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7fe869b3a37a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fe869b3e53c]
/lib/x86_64-linux-gnu/libc.so.6(fclose+0x103)[0x7fe869b27363]
./xorcipher[0x4009de]
./xorcipher[0x400d68]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fe869ada830]
./xorcipher[0x4007b9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 fd:01 1056628 /home/user1/Dropbox/SCOLARITY/L2Informatique/S3/Projet/Projet xorcipher/Code/programme final/test/xorcipher
00601000-00602000 r--p 00001000 fd:01 1056628 /home/user1/Dropbox/SCOLARITY/L2Informatique/S3/Projet/Projet xorcipher/Code/programme final/test/xorcipher
00602000-00603000 rw-p 00002000 fd:01 1056628 /home/user1/Dropbox/SCOLARITY/L2Informatique/S3/Projet/Projet xorcipher/Code/programme final/test/xorcipher
024a1000-024c2000 rw-p 00000000 00:00 0 [heap]
7fe864000000-7fe864021000 rw-p 00000000 00:00 0
7fe864021000-7fe868000000 ---p 00000000 00:00 0
7fe8698a4000-7fe8698ba000 r-xp 00000000 fd:01 136064 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fe8698ba000-7fe869ab9000 ---p 00016000 fd:01 136064 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fe869ab9000-7fe869aba000 rw-p 00015000 fd:01 136064 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fe869aba000-7fe869c7a000 r-xp 00000000 fd:01 137277 /lib/x86_64-linux-gnu/libc-2.23.so
7fe869c7a000-7fe869e7a000 ---p 001c0000 fd:01 137277 /lib/x86_64-linux-gnu/libc-2.23.so
7fe869e7a000-7fe869e7e000 r--p 001c0000 fd:01 137277 /lib/x86_64-linux-gnu/libc-2.23.so
7fe869e7e000-7fe869e80000 rw-p 001c4000 fd:01 137277 /lib/x86_64-linux-gnu/libc-2.23.so
7fe869e80000-7fe869e84000 rw-p 00000000 00:00 0
7fe869e84000-7fe869eaa000 r-xp 00000000 fd:01 137058 /lib/x86_64-linux-gnu/ld-2.23.so
7fe86a089000-7fe86a08c000 rw-p 00000000 00:00 0
7fe86a0a6000-7fe86a0a9000 rw-p 00000000 00:00 0
7fe86a0a9000-7fe86a0aa000 r--p 00025000 fd:01 137058 /lib/x86_64-linux-gnu/ld-2.23.so
7fe86a0aa000-7fe86a0ab000 rw-p 00026000 fd:01 137058 /lib/x86_64-linux-gnu/ld-2.23.so
7fe86a0ab000-7fe86a0ac000 rw-p 00000000 00:00 0
7ffea9648000-7ffea9669000 rw-p 00000000 00:00 0 [stack]
7ffea96b5000-7ffea96b7000 r--p 00000000 00:00 0 [vvar]
7ffea96b7000-7ffea96b9000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
问题似乎出在 xor 函数中,但我想不出是什么问题。根据 this,我的问题似乎是由取消引用的指针引起的。但根据 valgrind,这是一个开放的不可取消错误(我不知道它是什么,也无法在 google 上找到任何相关信息)。另一方面,我没有编译错误。
我的代码有什么问题?
程序如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void xor(char* name_file_in,char* name_file_out,char* name_key)
{
FILE *file_in;//file to encrypt
FILE *file_out;//encrypted file
unsigned char read_char;//character of the file
int count_char=0;//count number of characters in file
file_in=fopen(name_file_in,"r");
file_out=fopen(name_file_out,"w");
while ( fscanf(file_in,"%c",&read_char) != EOF)//each character of in file is read
{
read_char=read_char^name_key[count_char%strlen(name_key)];//read_char is encrypted according to key's length's modulo
fputc(read_char,file_out);//writing character to out file
count_char++;
}
fclose(file_in);
fclose(file_in);
}
int main(int argc,char* argv[])
{
xor(argv[1],argv[2],argv[3]);
return(0);
}
您正在关闭文件两次:
fclose(file_in);
fclose(file_in);
这是未定义的行为。
注意:我用 valgrind 只花了 5 秒就看到了...编译调试时使用 -g
!
您必须以二进制方式读写文件,即使它是文本文件。这是因为 XOR 运算符可能导致零字节,这会破坏文本模式下的读取例程。
file_in = fopen(name_file_in, "rb");
file_out = fopen(name_file_out, "wb");
此外,您必须检查以确保输入有效
if (!name_file_in) return;
if (!name_file_out) return;
if (!name_key) return;
如果文件句柄无效则不要继续
void xor(char* name_file_in, char* name_file_out, char* name_key)
{
if (!name_file_in) return;
if (!name_file_out) return;
if (!name_key) return;
FILE *file_in;
FILE *file_out;
unsigned char read_char;
int count_char = 0;
file_in = fopen(name_file_in, "rb");
file_out = fopen(name_file_out, "wb");
if(file_in && file_out)
{
while(fscanf(file_in, "%c", &read_char) > 0)
{
read_char ^= name_key[count_char%strlen(name_key)];
fputc(read_char, file_out);//writing character to out file
count_char++;
}
}
if (file_in)
fclose(file_in);
if (file_out)
fclose(file_out);
}
您可以将循环更改为 for(int i = 0; i < argc - 1; i++){...}
,因为您在每次迭代中访问 argv[i+1]
。
当执行我的程序时,我有这个错误:
*** Error in `./xorcipher': double free or corruption (!prev): 0x00000000024a1010 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fe869b317e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7fe869b3a37a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fe869b3e53c]
/lib/x86_64-linux-gnu/libc.so.6(fclose+0x103)[0x7fe869b27363]
./xorcipher[0x4009de]
./xorcipher[0x400d68]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fe869ada830]
./xorcipher[0x4007b9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 fd:01 1056628 /home/user1/Dropbox/SCOLARITY/L2Informatique/S3/Projet/Projet xorcipher/Code/programme final/test/xorcipher
00601000-00602000 r--p 00001000 fd:01 1056628 /home/user1/Dropbox/SCOLARITY/L2Informatique/S3/Projet/Projet xorcipher/Code/programme final/test/xorcipher
00602000-00603000 rw-p 00002000 fd:01 1056628 /home/user1/Dropbox/SCOLARITY/L2Informatique/S3/Projet/Projet xorcipher/Code/programme final/test/xorcipher
024a1000-024c2000 rw-p 00000000 00:00 0 [heap]
7fe864000000-7fe864021000 rw-p 00000000 00:00 0
7fe864021000-7fe868000000 ---p 00000000 00:00 0
7fe8698a4000-7fe8698ba000 r-xp 00000000 fd:01 136064 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fe8698ba000-7fe869ab9000 ---p 00016000 fd:01 136064 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fe869ab9000-7fe869aba000 rw-p 00015000 fd:01 136064 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fe869aba000-7fe869c7a000 r-xp 00000000 fd:01 137277 /lib/x86_64-linux-gnu/libc-2.23.so
7fe869c7a000-7fe869e7a000 ---p 001c0000 fd:01 137277 /lib/x86_64-linux-gnu/libc-2.23.so
7fe869e7a000-7fe869e7e000 r--p 001c0000 fd:01 137277 /lib/x86_64-linux-gnu/libc-2.23.so
7fe869e7e000-7fe869e80000 rw-p 001c4000 fd:01 137277 /lib/x86_64-linux-gnu/libc-2.23.so
7fe869e80000-7fe869e84000 rw-p 00000000 00:00 0
7fe869e84000-7fe869eaa000 r-xp 00000000 fd:01 137058 /lib/x86_64-linux-gnu/ld-2.23.so
7fe86a089000-7fe86a08c000 rw-p 00000000 00:00 0
7fe86a0a6000-7fe86a0a9000 rw-p 00000000 00:00 0
7fe86a0a9000-7fe86a0aa000 r--p 00025000 fd:01 137058 /lib/x86_64-linux-gnu/ld-2.23.so
7fe86a0aa000-7fe86a0ab000 rw-p 00026000 fd:01 137058 /lib/x86_64-linux-gnu/ld-2.23.so
7fe86a0ab000-7fe86a0ac000 rw-p 00000000 00:00 0
7ffea9648000-7ffea9669000 rw-p 00000000 00:00 0 [stack]
7ffea96b5000-7ffea96b7000 r--p 00000000 00:00 0 [vvar]
7ffea96b7000-7ffea96b9000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
问题似乎出在 xor 函数中,但我想不出是什么问题。根据 this,我的问题似乎是由取消引用的指针引起的。但根据 valgrind,这是一个开放的不可取消错误(我不知道它是什么,也无法在 google 上找到任何相关信息)。另一方面,我没有编译错误。
我的代码有什么问题?
程序如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void xor(char* name_file_in,char* name_file_out,char* name_key)
{
FILE *file_in;//file to encrypt
FILE *file_out;//encrypted file
unsigned char read_char;//character of the file
int count_char=0;//count number of characters in file
file_in=fopen(name_file_in,"r");
file_out=fopen(name_file_out,"w");
while ( fscanf(file_in,"%c",&read_char) != EOF)//each character of in file is read
{
read_char=read_char^name_key[count_char%strlen(name_key)];//read_char is encrypted according to key's length's modulo
fputc(read_char,file_out);//writing character to out file
count_char++;
}
fclose(file_in);
fclose(file_in);
}
int main(int argc,char* argv[])
{
xor(argv[1],argv[2],argv[3]);
return(0);
}
您正在关闭文件两次:
fclose(file_in);
fclose(file_in);
这是未定义的行为。
注意:我用 valgrind 只花了 5 秒就看到了...编译调试时使用 -g
!
您必须以二进制方式读写文件,即使它是文本文件。这是因为 XOR 运算符可能导致零字节,这会破坏文本模式下的读取例程。
file_in = fopen(name_file_in, "rb");
file_out = fopen(name_file_out, "wb");
此外,您必须检查以确保输入有效
if (!name_file_in) return;
if (!name_file_out) return;
if (!name_key) return;
如果文件句柄无效则不要继续
void xor(char* name_file_in, char* name_file_out, char* name_key)
{
if (!name_file_in) return;
if (!name_file_out) return;
if (!name_key) return;
FILE *file_in;
FILE *file_out;
unsigned char read_char;
int count_char = 0;
file_in = fopen(name_file_in, "rb");
file_out = fopen(name_file_out, "wb");
if(file_in && file_out)
{
while(fscanf(file_in, "%c", &read_char) > 0)
{
read_char ^= name_key[count_char%strlen(name_key)];
fputc(read_char, file_out);//writing character to out file
count_char++;
}
}
if (file_in)
fclose(file_in);
if (file_out)
fclose(file_out);
}
您可以将循环更改为 for(int i = 0; i < argc - 1; i++){...}
,因为您在每次迭代中访问 argv[i+1]
。