释放下面的“shifted_text”时出现以下错误。我已经检查了打印语句并注释掉了内容,它绝对是免费的(shifted_text)。其他免费命令工作正常。
调试错误! 检测到堆损坏:在 0x007D1F 处的正常 block (#77)之后...
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”。这些工作正常,没有 free(shifted_text) 程序也可以工作。
我是 C 新手,所以这可能很简单,但我看不到。
最佳答案
改变这个
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);
时,由于未定义的行为,您的程序都会正确运行。
顺便说一句:您的代码中有很多地方需要改进。例如,在 void Bring_in_text(void)
中:
while (!feof(fp))
{
text = (char*)malloc(100 * sizeof(char));
fgets(text, 100, fp);
}
覆盖前面的行甚至不处理它们?此外,此函数中不会释放 text
。
关于使用 free() 时 C 堆缓冲区损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36108813/