将无效参数传递给认为无效参数致命的函数

Posted

技术标签:

【中文标题】将无效参数传递给认为无效参数致命的函数【英文标题】:An invalid parameter was passed to a function that considers invalid parameters fatal 【发布时间】:2018-04-09 10:42:03 【问题描述】:

我希望你能帮助我。我有这个用于保存位图图像的功能,但文件名有问题。我想在文件名上保存带有当前日期的图像,但我目前的操作方式是“无效参数已传递给认为无效参数致命的函数”错误并且程序崩溃。

这是从主程序中获取名称的函数:

void DoSave(char *Name)

    time_t rawTime;
    struct tm *timeInfo;
    char buffer[100];
    string date;

    time(&rawTime);
    timeInfo = localtime(&rawTime);

    strftime(buffer, 100, " %c", timeInfo);
    date = buffer;

    string url("Images/");
    string name(Name);
    string extension(".bmp");

    string path = url + name + date + extension;

    // Open the file for writing
    FILE *f = fopen((const char*)&path, "wb");

    // Save the image as bmp file
    BmpHelper::SaveTo8bppBmpFile(f, (LONG)m_ImageSizeX, (LONG)m_ImageSizeY, (unsigned char*)videoImage);
    fclose(f);

这是保存位图的函数

void BmpHelper::SaveTo8bppBmpFile(FILE *output, LONG width, LONG height, unsigned char *buffer)

    f8bppHeader_.bfSize = (DWORD)(s8bppHeader_ + width * height);

    i8bppHeader_.biWidth = (LONG)width;
    i8bppHeader_.biHeight = -(LONG)height;

    fwrite(&f8bppHeader_, sizeof(BITMAPFILEHEADER), 1, output);
    fwrite(&i8bppHeader_, sizeof(BITMAPINFOHEADER), 1, output); // I get the error in this line
    fwrite(p8bpp, sizeof(RGBQUAD), 256, output);
    fwrite(buffer, width, height, output);

不确定你是否需要这个,但我也会添加它。

void BmpHelper::Init8bppHeaders()

    f8bppHeader_.bfType = 'MB'; // Will be inverted during the fwrite
    s8bppHeader_ = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD) + 256 * sizeof(RGBQUAD));
    f8bppHeader_.bfReserved1 = 0;
    f8bppHeader_.bfReserved2 = 0;
    f8bppHeader_.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);

    i8bppHeader_.biSize = sizeof(BITMAPINFOHEADER);
    i8bppHeader_.biPlanes = 1;
    i8bppHeader_.biBitCount = 8;
    i8bppHeader_.biCompression = BI_RGB;
    i8bppHeader_.biSizeImage = 0;
    i8bppHeader_.biXPelsPerMeter = 0;
    i8bppHeader_.biYPelsPerMeter = 0;
    i8bppHeader_.biClrUsed = 0;
    i8bppHeader_.biClrImportant = 0;

    for (size_t index = 0; index < 256; ++index)
    
        p8bpp[index].rgbBlue = (BYTE)index;
        p8bpp[index].rgbGreen = (BYTE)index;
        p8bpp[index].rgbRed = (BYTE)index;
        p8bpp[index].rgbReserved = 0;
    

如果我从路径中删除日期,它可以正常工作,但它只会使用给定的 url + 名称和文件格式保存文件。我需要日期来区分文件。你们能发现代码有什么问题吗?提前致谢。

【问题讨论】:

(const char*)&amp;path --> path.c_str() 该错误消息是运行时错误(或异常),通常由代码中某种形式的未定义行为引起。问题是导致问题的代码可能与发生错误的代码行无关(例如,一些代码滥用了指针,一些后来的代码崩溃了)。因此,由于您没有提供minimal reproducible example,因此获得有用帮助的机会很小。您可能还想看看***.com/questions/29412110/… 试过@molbdnilo,但不幸的是它仍然不起作用。所以代码看起来不错吧?如果我从文件名中删除日期部分,它通过@Peter 起作用,这不是很奇怪吗?我去看看链接,谢谢! 哪个函数导致这个运行时错误?您传递给该函数的参数值是多少?你需要检查fopenfwrite和其他c函数的结果。我怀疑文件没有被打开,因为路径无效。 嗨@VTT,它发生在这一行的 SaveTo8bppBmpFile 函数中:fwrite(&amp;i8bppHeader_, sizeof(BITMAPINFOHEADER), 1, output); 这就是我要传递给它的内容:SaveTo8bppBmpFile(f, (LONG)m_ImageSizeX, (LONG)m_ImageSizeY, (unsigned char*)videoImage); 单步执行程序似乎文件打开了但是当我得到它打破的那个功能。 【参考方案1】:

您的日期/时间字符串包含: 字符。 Windows 文件名不接受任何这些字符\/:*?"&lt;&gt;|。您必须用不同的字符替换 :

您的代码也没有考虑位图填充。仅当位图宽度(以字节为单位)为 4 的倍数时才有效。使用以下公式计算 size(而不是 width * height):

int size = ((width * bpp + 31) / 32) * 4 * height;

s8bppHeader_ = (DWORD)... 是一个错字! bfSize 计算不正确。

您可以使用 C++ 函数 std::fstream 而不是混合使用 C++ 和 C

例子:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <ctime>
#include <windows.h>

...
std::time_t t = std::time(nullptr);
char date[100];
std::strftime(date, sizeof(date), " %c", std::localtime(&t));
for(size_t i = 0, len = strlen(date); i < len; i++)
    if(date[i] == ':')
        date[i] = ','; //use a different character

char *Name = "_abc";
string url("c:\\test\\");
string name(Name);
string extension(".bmp");
string path = url + name + date + extension;

int width = i8bppHeader_.biWidth;
int height = i8bppHeader_.biHeight;
int bpp = i8bppHeader_.biBitCount;

int size = ((width * bpp + 31) / 32) * 4 * height;

f8bppHeader_.bfType = 'MB'; // Will be inverted during the fwrite
f8bppHeader_.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
    + 256 * sizeof(RGBQUAD) + size;
f8bppHeader_.bfReserved1 = 0;
f8bppHeader_.bfReserved2 = 0;
f8bppHeader_.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
    + 256 * sizeof(RGBQUAD);

ofstream fout(path, ios::binary);
fout.write((char*)&f8bppHeader_, sizeof(f8bppHeader_));
fout.write((char*)&i8bppHeader_, sizeof(i8bppHeader_));
fout.write((char*)p8bpp, 256 * sizeof(RGBQUAD));
fout.write((char*)buffer, size);

【讨论】:

感谢@Barmak Shemirani。多亏了你,我才能使用 ofstream 而不是 FILE 让它工作。出于某种原因,即使我使用了没有禁止字符的格式,使用 FILE 也不喜欢我使用日期。很奇怪......但是,再次感谢!如果没有你的回答,我不确定我是否会很快让它工作!干杯! :D 对不起@Barmak Shemirani,现在才看到,已经完成了。

以上是关于将无效参数传递给认为无效参数致命的函数的主要内容,如果未能解决你的问题,请参考以下文章

将参数传递给 pthread_create - 从 void(*)() 到 void(*)(void*) 的无效转换

Jquery DataTable 将参数传递给ajax 调用asp.net。无效的 JSON 原语

从 rexx 代码向 ispf 宏传递参数时出现无效长度错误

如何使用 SwiftUI 将参数传递给 Button 的操作

c语言中atoi编译错误的问题

如何返回 404 状态,其中无效参数被传递到我的 ASP.NET MVC 控制器?