Функция, вызываемая объектом output
того же класса, что и объект input
, кажется, вызывает непредвиденное поведение и перезаписывает объект input
'malloc
данные приватного члена (адреса указателя остаются теми же)
Для объекта output
оба значения *fileStr
и *p_file
имеют значение NULL, а для input
обе точки данных
И CASE1
/ CASE2
, или комбинация каждого #ifdef
приведет к изменению данных input.fileStr
input.fileStr
сами данные malloc
'изменяются class1::open
при вызове (вызывается только input
) - иначе это NULL-указатель по умолчанию
Заголовок
class class1
{
private:
FILE *p_file = NULL;
char *fileStr = NULL;
bool encrypt_step1();
public:
bool open(char *pathto);
bool create(char *pathto);
bool encrypt();
~class1();
};
bool sub_function(char *pathIN);
Исходный код
bool class1::open(char *pathto)
{
if (PathFileExistsA(pathto))
this->p_file = fopen(pathto, "rb+");
else
return 0;
if (!(this->p_file))
{
printf("Can't open\n");
return 0;
}
fseek(p_file, 0, SEEK_END);
long filesize = ftell(p_file);
fseek(p_file, 0, SEEK_SET);
this->fileStr = (char*)malloc(filesize+1);
this->fileStr[(fread(this->fileStr, 1, filesize, this->p_file))] = '\0';
return 1;
}
bool class1::create(char *pathto)
{
#ifdef CASE1
if (PathFileExistsA(pathto))
{
char pathtobak[MAX_PATH];
strcpy(pathtobak, pathto);
strcat(pathtobak, ".bak");
int i = 0;
char a[11];
if (PathFileExistsA(pathtobak))
{
while (1)
{
i++;
*a = '\0';
itoa(i, a, 10);
char *reset = pathtobak + strlen(pathtobak);
strcat(pathtobak, a);
if (!PathFileExistsA(pathtobak))
break;
*reset = '\0';
}
}
std::experimental::filesystem::copy_file(pathto, pathtobak);
}
#endif
#ifdef CASE2
this->p_file = fopen(pathto, "wb");
#endif
#ifndef NOERRORS
if (this->p_file == NULL)
return 0;
else
return 1;
#endif
}
class1::~class1()
{
if (this->fileStr)
{
free(this->fileStr);
this->fileStr = NULL;
}
if (this->p_file)
{
fclose(this->p_file);
this->p_file = NULL;
}
}
bool sub_function(char *pathIN)
{
class1 input;
input.open(pathIN);
input.encrypt();//omitted since this should be irrelevant
char pathOUT[MAX_PATH];
strcpy(pathOUT, pathIN);
char *OUText = pathOUT;
OUText += (strlen(pathOUT)-3);
*OUText = '\0';
strcat(pathOUT, "ext");
class1 output;
output.create(pathOUT);//bug here
char *next = input.get_fileStr();
...
}
Это похоже на нарушение доступа к памяти, но даже CASE1
, который просто ищет дубликаты файлов с использованием только локальной переменной, по-прежнему вызывает непредвиденное поведение, поэтому у меня есть проблемы с определением причины
Кажется, память уже освобождена
Наиболее вероятная причина - пометка памяти как свободной, но я не освобождаю ее за пределами деструктора, но при дальнейшем запуске программы после вызова деструктора input
free(input.fileStr)
произойдет сбой с is_block_type_valid(header->_block_use)
исключением < бр />
Актуальная проблема с рабочим примером
Исходный код, начиная с sub_function::input.encrypt()
bool class1::encrypt_step1()
{
bool *strBOOL_11_00 = (bool*)malloc(((strlen(this->fileStr)) + 1) * ((sizeof(bool)) * 8));
bool *strBOOL_10_01 = (bool*)malloc(((strlen(this->fileStr)) + 1) * ((sizeof(bool)) * 8));
bool *strBOOL_10_11 = (bool*)malloc(((strlen(this->fileStr)) + 1) * ((sizeof(bool)) * 8));
char *fileStrIt = this->fileStr;
char *fileStrIt2 = ((this->fileStr) + 1);
bool *next1100 = strBOOL_11_00;
bool *next1001 = strBOOL_10_01;
bool *next1011 = strBOOL_10_11;
//translating to binary array iterating through pointers above one by one happens here
//char->bin/encrypt/bin->char
//ommited
//reallocation to fit new encrypted and translated back to char that caused issues
#ifdef ISSUE
char *fileStr_temp = (char *)realloc(this->fileStr, ((next1011 - strBOOL_10_11) + (next1001 - strBOOL_10_01) + (next1100 - strBOOL_11_00) + 1));
if (!fileStr_temp)
return 0;
//original fileStr points at freed memory
#endif
#ifdef CORRECT
char *fileStr_temp = (char *)realloc(this->fileStr, ((next1011 - strBOOL_10_11) + (next1001 - strBOOL_10_01) + (next1100 - strBOOL_11_00) + 1));
if (!fileStr_temp)
return 0;
else
this->fileStr = fileStr_temp;//original fileStr points at new adress with reallocated data
#endif
free(strBOOL_11_00);
strBOOL_11_00 = NULL;
free(strBOOL_10_01);
strBOOL_10_01 = NULL;
free(strBOOL_10_11);
strBOOL_10_11 = NULL;
return 1;
}
bool class1::encrypt()
{
encrypt_step1();
...//other steps (irrelevant)
return 1;
}