malloc():损坏的顶部大小
malloc(): corrupted top size
我正在开发一个解密文件中某行文本的程序。首先,我创建的另一个源代码要求转换和一些文本。源代码加密文本并将其写入文件。
然后,我尝试使用下面的代码(另一个源代码)解密指定的文件。获取文件名。从文件名中获取 shift。文件中写入的每个字符都被复制,借助函数 caesar_decrypt -reversing caesar encrypt 移动 shift 的值,我也有。但是,给定字符的 ascii 值必须介于 32 和 127 之间,才能转换为另一个 ascii 值介于 32 和 127 之间的字符。
我定义了我的模函数,它封装了余数运算符 - 正数模 - 和负数模。我还定义了 strip 函数,它的工作方式与 python 中的 strip 函数相同。除了空格,它会删除所有文字。我还有getIn(),就是python.
的input()
我尝试通过打印和使用 gdb 进行调试。没有有效的结果。我已经在 Whosebug 中研究过这个主题。找到一个条目。答案没有解决我的具体问题。
注意:我复制了整个程序,因为我认为您需要必要的详细信息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
/*GETIN FUNCTION*/
char* getIn()
{
char *line = NULL, *tmp = NULL;
size_t size = 0, index = 0;
int ch = EOF;
while (ch)
{
ch = getc(stdin);
/* Check if we need to stop. */
if (ch == EOF || ch == '\n')
ch = 0;
/* Check if we need to expand. */
if (size <= index)
{
size += sizeof(char);
tmp = realloc(line, size);
if (!tmp)
{
free(line);
line = NULL;
break;
}
line = tmp;
}
/* Actually store the thing. */
line[index++] = ch;
}
return line;
}
/*FUNCTION THAT CONVERTS TO NUMERIC CHARACTER, PRECURSOR OF DIGITS OF SHIFT*/
char make_numeric(char ch)
{
if(ch<91 && ch>63) return ch-16;
if(ch<123 && ch>95) return ch-48;
if(ch<58 && ch>47) return ch;
return ch+16;
}
/*STRIP FUNCTION*/
char* strip(char* str,int length)
{
char *start=str,*end=&str[length-1];
while(*start>0 && *start<33 || *start==127) ++start;
if(!*start) return start;
while(*end>=0 && *end<33 || *end==127) --end;
++end;
*end=0;
return start;
}
/*DECRYPTOR FUNCTION*/
char *caesar_decrypt(char *message_to_decrypt, void *shift)
{
int length=strlen(message_to_decrypt),i;
char* decrypted_message;
if(!message_to_decrypt) return NULL;
if(!(decrypted_message=calloc(length+1,sizeof(char)))) return NULL;
for(i=0;i<length;++i)
{
decrypted_message[i]=mod((message_to_decrypt[i]-33-*((int*)shift)),94)+33;
}
return decrypted_message;
}
/*THE MAIN PROGRAM*/
int main()
{
int shift,len_chshift,init,len_filename,i=0;
char *chshift,*line=NULL,*decrypted_line,*stripped_line,chinit,chlen_chshift;
char *filename=NULL,*newfilename=NULL;
FILE *oldfile=NULL;
FILE *newfile=NULL;
size_t lenline,len=0;
printf("-9");
/*FILENAME*/
printf("Enter the file name: ");
/*printf("-8");*/
filename=getIn();
/*printf("-7");*/
if(!access(filename,F_OK))
{
len_filename=strlen(filename);
/*printf("-6");*/
i=len_filename;
while(filename[i]!='.') --i;
chlen_chshift=filename[i-1];
chlen_chshift=make_numeric(chlen_chshift);
len_chshift=chlen_chshift-48;
/*printf("-5");*/
chshift=calloc(len_chshift+1,1);
/*NEWFILENAME*/
newfilename=calloc(i+1,1);
/*printf("-4");*/
strncpy(newfilename,filename,i);
/*printf("-3");*/
strcat(newfilename,"(decrypted).txt");
/*printf("-2");*/
chinit=make_numeric(filename[0]);
init=chinit-48;
/*SHIFT*/
i=0;
/*printf("-1");*/
while(i!=len_chshift)
{
chshift[i]=make_numeric(filename[(i+1)*init]);
++i;
}
/*printf("0");*/
shift=atoi(chshift);
/*printf("1");*/
if(!(oldfile=fopen(filename,"r")))
{
perror("Error");
if(newfilename) free(newfilename);
if(filename) free(filename);
if(chshift) free(chshift);
exit(1);
}
/*printf("2");*/
if(!(newfile=fopen(newfilename,"+ab")))
{
perror("Error");
if(newfilename) free(newfilename);
if(filename) free(filename);
if(chshift) free(chshift);
fclose(oldfile);
exit(1);
}
while ((lenline = getline(&line, &len, oldfile)) != -1)
{
stripped_line=strip(line,lenline);
decrypted_line=caesar_decrypt(stripped_line, &shift);
if(!decrypted_line)
{
printf("Could not allocate memory\n");
if(newfilename) free(newfilename);
if(filename) free(filename);
if(chshift) free(chshift);
exit(1);
}
fprintf(newfile,"%s\n",decrypted_line);
if(decrypted_line) free(decrypted_line);
decrypted_line=NULL;
free(line);
line=NULL;
stripped_line=NULL;
decrypted_line=NULL;
}
free(line);
line=NULL;
}
else
{
printf("Cannot access the file.");
if(filename) free(filename);
exit(0);
}
if(newfilename) free(newfilename);
if(filename) free(filename);
if(chshift) free(chshift);
fclose(oldfile);
fclose(newfile);
return 0;
}
该程序需要创建一个文件,该文件的上下文是另一个文件的解密克隆,该文件的名称由用户在开头提供。但是,它会在第一个 fopen 之前抛出:
malloc(): corrupted top size
Aborted (core dumped)
当我取消注释每个 printf 行时,它在 getIn() 和 printf("-7"); 的行之间给出相同的错误。当注释 printfs 时,我观察到文件名保存写入的值,该值由 getIn() 返回。因此,我认为 getIn() 不是问题。
EDIT(1):我添加了 2 个 headers,但仍然出现相同的错误。
EDIT(2):我删除了所有不必要的 headers。
EDIT(3):既然我被要求,我将尝试通过一个例子来说明:假设我有一个名为
的文件
2/b*A".txt
两行代码
%52
abcd
我把文件名输入程序。
1).之前的最后一个字符是",转换成数字2 .我们理解shift是两位数。
2)第一个字符是发起者,也就是2,就是我们需要反复跳转的字符个数。我们将跳转两个字符两次,因为我们有两位数的移位数。
3)我们现在已经将字符 b 和 A 分别转换为 2 和 1。我们的移位是 21。第一个字符 %(37) 向后移位到 n(110) 等等,我们需要创建一个内容为新文件:
n~#
LMNO
感谢任何帮助。先感谢您。另外,我提到的变量是特定区间之间的任意字符。详情请查看源码,或者我建议你在本地工作,因为我提供了整个程序。
对于ascii码:
https://www.asciitable.com/
如果您对凯撒密码感兴趣:
https://en.wikipedia.org/wiki/Caesar_cipher
您在 newfilename
中发生缓冲区溢出:
/* here you declare that the string pointed to by newfilename may contain `i`
chars + zero-termination...*/
newfilename=calloc(i+1,1);
/* Here `i` is less than `strlen(filename)`, so only i characters from `filename`
will be copied, that does NOT include the zero-termination
(but it will be zero-terminated because the last byte in the buffer was
already cleared by `calloc`) */
strncpy(newfilename,filename,i);
/* Here `newfilename` is full, and `strcat` will write outside buffer!! Whatever
happens after this line is undefined behaviour */
strcat(newfilename,"(decrypted).txt");
所以你必须为newfilename
分配足够的space:
newfilename = calloc (i + strlen("(decrypted).txt") + 1, 1);
我正在开发一个解密文件中某行文本的程序。首先,我创建的另一个源代码要求转换和一些文本。源代码加密文本并将其写入文件。
然后,我尝试使用下面的代码(另一个源代码)解密指定的文件。获取文件名。从文件名中获取 shift。文件中写入的每个字符都被复制,借助函数 caesar_decrypt -reversing caesar encrypt 移动 shift 的值,我也有。但是,给定字符的 ascii 值必须介于 32 和 127 之间,才能转换为另一个 ascii 值介于 32 和 127 之间的字符。
我定义了我的模函数,它封装了余数运算符 - 正数模 - 和负数模。我还定义了 strip 函数,它的工作方式与 python 中的 strip 函数相同。除了空格,它会删除所有文字。我还有getIn(),就是python.
的input()我尝试通过打印和使用 gdb 进行调试。没有有效的结果。我已经在 Whosebug 中研究过这个主题。找到一个条目。答案没有解决我的具体问题。
注意:我复制了整个程序,因为我认为您需要必要的详细信息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
/*GETIN FUNCTION*/
char* getIn()
{
char *line = NULL, *tmp = NULL;
size_t size = 0, index = 0;
int ch = EOF;
while (ch)
{
ch = getc(stdin);
/* Check if we need to stop. */
if (ch == EOF || ch == '\n')
ch = 0;
/* Check if we need to expand. */
if (size <= index)
{
size += sizeof(char);
tmp = realloc(line, size);
if (!tmp)
{
free(line);
line = NULL;
break;
}
line = tmp;
}
/* Actually store the thing. */
line[index++] = ch;
}
return line;
}
/*FUNCTION THAT CONVERTS TO NUMERIC CHARACTER, PRECURSOR OF DIGITS OF SHIFT*/
char make_numeric(char ch)
{
if(ch<91 && ch>63) return ch-16;
if(ch<123 && ch>95) return ch-48;
if(ch<58 && ch>47) return ch;
return ch+16;
}
/*STRIP FUNCTION*/
char* strip(char* str,int length)
{
char *start=str,*end=&str[length-1];
while(*start>0 && *start<33 || *start==127) ++start;
if(!*start) return start;
while(*end>=0 && *end<33 || *end==127) --end;
++end;
*end=0;
return start;
}
/*DECRYPTOR FUNCTION*/
char *caesar_decrypt(char *message_to_decrypt, void *shift)
{
int length=strlen(message_to_decrypt),i;
char* decrypted_message;
if(!message_to_decrypt) return NULL;
if(!(decrypted_message=calloc(length+1,sizeof(char)))) return NULL;
for(i=0;i<length;++i)
{
decrypted_message[i]=mod((message_to_decrypt[i]-33-*((int*)shift)),94)+33;
}
return decrypted_message;
}
/*THE MAIN PROGRAM*/
int main()
{
int shift,len_chshift,init,len_filename,i=0;
char *chshift,*line=NULL,*decrypted_line,*stripped_line,chinit,chlen_chshift;
char *filename=NULL,*newfilename=NULL;
FILE *oldfile=NULL;
FILE *newfile=NULL;
size_t lenline,len=0;
printf("-9");
/*FILENAME*/
printf("Enter the file name: ");
/*printf("-8");*/
filename=getIn();
/*printf("-7");*/
if(!access(filename,F_OK))
{
len_filename=strlen(filename);
/*printf("-6");*/
i=len_filename;
while(filename[i]!='.') --i;
chlen_chshift=filename[i-1];
chlen_chshift=make_numeric(chlen_chshift);
len_chshift=chlen_chshift-48;
/*printf("-5");*/
chshift=calloc(len_chshift+1,1);
/*NEWFILENAME*/
newfilename=calloc(i+1,1);
/*printf("-4");*/
strncpy(newfilename,filename,i);
/*printf("-3");*/
strcat(newfilename,"(decrypted).txt");
/*printf("-2");*/
chinit=make_numeric(filename[0]);
init=chinit-48;
/*SHIFT*/
i=0;
/*printf("-1");*/
while(i!=len_chshift)
{
chshift[i]=make_numeric(filename[(i+1)*init]);
++i;
}
/*printf("0");*/
shift=atoi(chshift);
/*printf("1");*/
if(!(oldfile=fopen(filename,"r")))
{
perror("Error");
if(newfilename) free(newfilename);
if(filename) free(filename);
if(chshift) free(chshift);
exit(1);
}
/*printf("2");*/
if(!(newfile=fopen(newfilename,"+ab")))
{
perror("Error");
if(newfilename) free(newfilename);
if(filename) free(filename);
if(chshift) free(chshift);
fclose(oldfile);
exit(1);
}
while ((lenline = getline(&line, &len, oldfile)) != -1)
{
stripped_line=strip(line,lenline);
decrypted_line=caesar_decrypt(stripped_line, &shift);
if(!decrypted_line)
{
printf("Could not allocate memory\n");
if(newfilename) free(newfilename);
if(filename) free(filename);
if(chshift) free(chshift);
exit(1);
}
fprintf(newfile,"%s\n",decrypted_line);
if(decrypted_line) free(decrypted_line);
decrypted_line=NULL;
free(line);
line=NULL;
stripped_line=NULL;
decrypted_line=NULL;
}
free(line);
line=NULL;
}
else
{
printf("Cannot access the file.");
if(filename) free(filename);
exit(0);
}
if(newfilename) free(newfilename);
if(filename) free(filename);
if(chshift) free(chshift);
fclose(oldfile);
fclose(newfile);
return 0;
}
该程序需要创建一个文件,该文件的上下文是另一个文件的解密克隆,该文件的名称由用户在开头提供。但是,它会在第一个 fopen 之前抛出:
malloc(): corrupted top size
Aborted (core dumped)
当我取消注释每个 printf 行时,它在 getIn() 和 printf("-7"); 的行之间给出相同的错误。当注释 printfs 时,我观察到文件名保存写入的值,该值由 getIn() 返回。因此,我认为 getIn() 不是问题。
EDIT(1):我添加了 2 个 headers,但仍然出现相同的错误。
EDIT(2):我删除了所有不必要的 headers。
EDIT(3):既然我被要求,我将尝试通过一个例子来说明:假设我有一个名为
的文件2/b*A".txt
两行代码
%52
abcd
我把文件名输入程序。
1).之前的最后一个字符是",转换成数字2 .我们理解shift是两位数。
2)第一个字符是发起者,也就是2,就是我们需要反复跳转的字符个数。我们将跳转两个字符两次,因为我们有两位数的移位数。
3)我们现在已经将字符 b 和 A 分别转换为 2 和 1。我们的移位是 21。第一个字符 %(37) 向后移位到 n(110) 等等,我们需要创建一个内容为新文件:
n~#
LMNO
感谢任何帮助。先感谢您。另外,我提到的变量是特定区间之间的任意字符。详情请查看源码,或者我建议你在本地工作,因为我提供了整个程序。
对于ascii码: https://www.asciitable.com/
如果您对凯撒密码感兴趣: https://en.wikipedia.org/wiki/Caesar_cipher
您在 newfilename
中发生缓冲区溢出:
/* here you declare that the string pointed to by newfilename may contain `i`
chars + zero-termination...*/
newfilename=calloc(i+1,1);
/* Here `i` is less than `strlen(filename)`, so only i characters from `filename`
will be copied, that does NOT include the zero-termination
(but it will be zero-terminated because the last byte in the buffer was
already cleared by `calloc`) */
strncpy(newfilename,filename,i);
/* Here `newfilename` is full, and `strcat` will write outside buffer!! Whatever
happens after this line is undefined behaviour */
strcat(newfilename,"(decrypted).txt");
所以你必须为newfilename
分配足够的space:
newfilename = calloc (i + strlen("(decrypted).txt") + 1, 1);