gpt4 book ai didi

c++ - _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) C++ 文件

转载 作者:行者123 更新时间:2023-11-28 00:16:48 25 4
gpt4 key购买 nike

我知道有几篇关于此错误的帖子,但它们都是针对特定情况的。我正在制作一个文件拆分/连接器,它具有以下要求:-用户必须输入文件名/输入路径和输出文件夹。我用将原始文件拆分为 N 部分(用户必须输入)的基本部分编写了拆分函数,一切都很好。然后我对该函数进行了一些修改以满足“输出文件夹”的要求,然后当我运行该程序时,出现了该错误(尽管已成功构建)。有人可以解释/澄清我在代码中做错了什么吗?我仍然是处理文件/内存泄漏的初学者,因此感谢所有帮助/批评。

char *GetFileName(char *path)
{
char *filename = strrchr(path, '\\');
if (filename == NULL)
filename = path;
else
filename++;
return filename;
}

void split_F(const char* file_name, const char* output_folder, int number_of_part)
{
FILE *fp_read = fopen(file_name, "rb");

//calculate file size
int file_size;
fseek(fp_read, 0L, SEEK_END);
file_size = ftell(fp_read);
rewind(fp_read); //reset file pointer

//calculate number of parts
long size_of_part;
size_of_part = (int)ceil((double)file_size / number_of_part);
cout << "Total files after split: " << number_of_part << endl
<< "...Processing..." << endl;


//extract file name
char *first_part = new char[255];
char *temp = new char[255];
strcpy(temp, file_name);
first_part = GetFileName(temp);
cout << endl << "File name is: " << first_part;


//main process
char* name = new char[255];
strcpy(name, output_folder);
int bytesRemaining = file_size;

//create buffer
char *buffer = new char[size_of_part];

for (int count = 1; count <= number_of_part; count++)
{

sprintf(name, "%s.part_%03d", first_part, count); //attach file name to output directory

FILE *fp_write = fopen(name, "wb");

long partSize;
if (bytesRemaining > size_of_part)
{
partSize = size_of_part;
}
else
{
partSize = bytesRemaining;
}

fread(buffer, partSize, 1, fp_read);
fwrite(buffer, partSize, 1, fp_write);

cout << "> File: " << name << " done babe!" << endl;

fclose(fp_write);
}
fclose(fp_read);

delete[] buffer;
delete[] name;
delete[] temp;
delete[] first_part;
}

最佳答案

首先,您的代码有很多问题,都是因为使用了 C 风格编码而不是使用 C++。相反,如果您使用 std::string 和 C++ 流,很多这些问题都会自行解决。

第一个问题是您从未检查文件是否存在:

FILE *fp_read = fopen(file_name, "rb");

如果 fp_read 为 NULL,您就不会检查它,并且您的代码会继续运行,就好像没有任何错误一样。这是不正确的。

然后在您的代码中执行此操作:

  FILE *fp_write = fopen(name, "wb");

同样,当 fp_write 可能为 NULL 时,您没有检查它是否正常。


但让我们假设 fp_readfp_write 不为 NULL

//extract file name
char *first_part = new char[255];
char *temp = new char[255];
strcpy(temp, file_name);

上述有 2 个潜在问题。

第一个问题是您没有检查以确保 file_name 少于 255 个字符。如果 file_name 比预期的大,则在调用 strcpy 时会覆盖内存。使用 strncpymemcpy 声明要复制的数字字符。

第二个问题比较微妙,就是你调用了两次new[]。如果第二次调用 new[] 抛出异常怎么办?您将如何释放对 new[] 的第一次调用?你不能。此外,由于抛出异常,您的输入文件仍将打开。

这就是为什么在这些情况下应该使用 std::stringifstream ofstream 的原因。如果函数出于任何原因返回,这些类型会自动释放分配的任何资源。使用 C 风格的字符串和 I/O 会使您容易受到泄漏的影响。

同样的问题:

//main process
char* name = new char[255];
strcpy(name, output_folder);
int bytesRemaining = file_size;

//create buffer
char *buffer = new char[size_of_part];

所有这些对 new[] 的调用都可能抛出,从而离开此函数,并导致内存泄漏和打开的文件句柄。


另一个问题是您需要确保您的 buffer 不会溢出。这段代码:

    long partSize;
if (bytesRemaining > size_of_part)
{
partSize = size_of_part;
}
else
{
partSize = bytesRemaining;
}

可以缩短为:

partSize = std::min(bytesRemaining, size_of_part);

这清楚地表明了您的意图。


另一个问题是您的 bytesRemaining 在您编写输出的循环中永远不会更新。你应该有

bytesRemaining -= partSize;

在循环中。

关于c++ - _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) C++ 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29713023/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com