我在下面释放“shifted_text”时遇到以下错误。我已经检查过print语句并对事情进行评论,这肯定是免费的(shifted_text)。其他免费命令工作正常。
调试错误! HEAP CORRUPTION DETECTED:正常阻止(#77)0x007D1F ...
CRT检测到应用程序在堆缓冲区结束后写入内存。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parse(int argc, char *argv[]);
char * shift_text(char *sometext);
char shift_letter(char letter, char shift);
void bring_in_text(void);
void write_to_file(char *sometext);
char *flag;
char *password;
char *text;
int main(int argc, char *argv[])
{
parse(argc, argv);
char *shifted_text;
// at this point flag can only be -e, -d, -df, -ef
if (strcmp(flag, "-e") == 0 || strcmp(flag, "-d") == 0)
{
// location to store the shifted text
shifted_text = (char*)malloc(strlen(text) * sizeof(char));
shift_text(shifted_text);
printf("%s\n", shifted_text);
}
else
{
bring_in_text();
// location to store the shifted text
shifted_text = (char*)malloc(strlen(text) * sizeof(char));
shift_text(shifted_text);
write_to_file(shifted_text);
}
free(shifted_text);
free(text);
free(flag);
free(password);
return 0;
}
void write_to_file(char *sometext)
{
if (strcmp(flag, "-df") == 0)
{
FILE *fp;
fp = fopen("plaintext.txt", "w");
if (fp == NULL)
{
puts("Unable to open file");
exit(1);
}
fprintf(fp, sometext);
fclose(fp);
}
else if (strcmp(flag, "-ef") == 0)
{
FILE *fp;
fp = fopen("ciphertext.txt", "w");
if (fp == NULL)
{
puts("Unable to open file");
exit(1);
}
fprintf(fp, sometext);
fclose(fp);
}
}
void bring_in_text(void)
{
if (strcmp(flag, "-df") == 0)
{
FILE *fp;
fp = fopen("ciphertext.txt", "r");
if (fp == NULL)
{
puts("Unable to open file");
exit(1);
}
while (!feof(fp))
{
text = (char*)malloc(100 * sizeof(char));
fgets(text, 100, fp);
}
fclose(fp);
}
else if (strcmp(flag, "-ef") == 0)
{
FILE *fp;
fp = fopen("plaintext.txt", "r");
if (fp == NULL)
{
puts("Unable to open file");
exit(1);
}
while (!feof(fp))
{
text = (char*)malloc(100 * sizeof(char));
fgets(text, 100, fp);
}
fclose(fp);
}
}
char * shift_text(char *shifted_text)
{
char *temptext;
temptext = text;
char *tempshiftedtext;
tempshiftedtext = shifted_text;
// space for 10 characters plus null
char *temppswd;
temppswd = password;
for (int i = 0; i < strlen(text); i++)
{
char a;
if (*temptext >= 97 && *temptext <= 122)
{
a = shift_letter(*(temptext + i), *(temppswd + (i % strlen(password))));
*(tempshiftedtext + i) = a;
}
else
*(tempshiftedtext + i) = *(temptext + i);
}
*(tempshiftedtext + strlen(text)) = '\0';
}
char shift_letter(char letter, char shift)
{
if (strcmp(flag, "-e") == 0 || strcmp(flag, "-ef") == 0)
{
letter = letter - 97;
shift = shift - 97;
int shifted_letter = letter + shift;
if (shifted_letter > 25)
shifted_letter %= 26;
shifted_letter += 97;
return (char)shifted_letter;
}
else if (strcmp(flag, "-d") == 0 || strcmp(flag, "-df") == 0)
{
int shifted_letter = letter - 97;
shift = shift - 97;
int letter = shifted_letter - shift;
letter %= 26; // mod seems to allow negative results, so if its still negative. add another val equal to modulus
if (letter < 0)
letter += 26;
letter += 97;
return (char)letter;
}
}
void parse(int argc, char *argv[])
{
if (argc == 4)
{
// internally calls malloc on strlen(argv[i])
flag = _strdup(argv[1]);
password = _strdup(argv[2]);
text = _strdup(argv[3]);
if (strlen(password) > 10)
{
puts("Password too long");
exit(1);
}
else if (strcmp(flag, "-e") != 0 && strcmp(flag, "-d") != 0)
{
puts("Incorrect flag");
exit(1);
}
}
else if (argc == 3)
{
// internally calls malloc on strlen(argv[i])
flag = _strdup(argv[1]);
password = _strdup(argv[2]);
if (strlen(password) > 10)
{
puts("Password too long");
exit(1);
}
else if (strcmp(flag, "-ef") != 0 && strcmp(flag, "-df") != 0)
{
puts("Incorrect flag");
exit(1);
}
}
else
{
puts("Incorrect arguements");
exit(1);
}
}
函数解析只是将命令行参数存储在全局中。移位功能将字母移动了一些数字。例如,'A'移位2将是'C'。这些工作正常,没有程序可用的免费(shifted_text)。
我是C的新手,所以它可能很简单,但我看不到它。
答案 0 :(得分:1)
更改此
shifted_text = (char*)malloc(strlen(text) * sizeof(char));
到
shifted_text = malloc((strlen(text) + 1) * sizeof(char)); // don't cast
C样式字符串始终具有空终止符,表示字符串的结尾。例如,"foo"
在内存中存储为'f', 'o', 'o', '\0'
。所以你必须
我怀疑堆缓冲区损坏不是由free(shifted_text);
引起的。由于没有足够的内存分配给shifted_text
,因此调用了未定义的行为,使一切成为可能。所以你的程序可能运行正常或崩溃。也许只是巧合,每次free(shifted_text);
被注释掉,由于未定义的行为,你的程序运行正常。
BTW:您的代码中有许多地方需要改进。例如,在void bring_in_text(void)
:
while (!feof(fp))
{
text = (char*)malloc(100 * sizeof(char));
fgets(text, 100, fp);
}
覆盖以前的行甚至没有处理它们?此外,此函数中未释放text
。
答案 1 :(得分:0)
strdup
分配strlen + 1个字符,你只分配strlen字符。当您在移位文本的末尾写入null时,您将溢出缓冲区。