奇怪的字符串比较崩溃

C++: Funny string comparison crash

本文关键字:比较 崩溃 字符串      更新时间:2023-10-16

我试图在c++程序中采用一个简单的命令行参数来触发不同的程序行为-当您包含"y"(或任何以y开头的字符串-我真的不在乎)时,程序显示一些中间结果。
当我运行

ccal pix.txt

一切正常

当我使用

ccal pixel .txt yes

它运行正常,显示我的图片,并在最后崩溃。

,

ccal px .txt no

在没有显示像素的情况下运行一切正常(就像它应该的那样),并且仍然在最后崩溃。

这里是相关的代码-我做错了什么?

void dumpFloatMatrix(Mat m){
for(int i = 0; i < m.cols; i++){
    for(int j = 0; j < m.rows; j++){
        char *buff = new char[10];
        sprintf(buff, "%5.1f ", m.at<float>(i,j));
        cout << buff;
        delete buff;
    }
    cout << endl;
}
 }
int main(int argc, char *argv[]){
char* outFile;
bool showPix = false;
// Take in command line args
switch(argc){
case 3:
    if(strncmp(argv[2], "y", 1) == 0)
        showPix = true;
    outFile = argv[1];
    break;
case 2:
    outFile = argv[1];
    break;
default:
    cout << "Usage: ccal INPUT_LIST_FILE" << endl;
    return -1;
}
Mat cameraMatrix(3, 3, CV_32FC1);
dumpFloatMatrix(cameraMatrix);
return 0;
}

奇怪的是,即使我将案例3中的测试转换为这样的内容:

        if(argv[2][0] == 'y')

我仍然得到相同的行为。我怎么也想不明白为什么。

对不起,但这是纯粹的疯狂:

for(int j = 0; j < m.rows; j++){
    char *buff = new char[10];
    sprintf(buff, "%5.1f ", m.at<float>(i,j));
    cout << buff;
    delete buff;
}

对于一个10字节的数组调用new/delete将花费16-32字节的内存加上你想要的10字节[可能四舍五入到16,32或64字节]。和分别调用new和delete。是的,我确信cout << buff将需要更多的循环,但这些在某种程度上是必要的。

要么使用:

for(int j = 0; j < m.rows; j++){
    char buff[10];
    sprintf(buff, "%5.1f ", m.at<float>(i,j));
    cout << buff;
}

或者使用c++风格的格式:

for(int j = 0; j < m.rows; j++){
    cout << precision(1) << setw(5) << m.at<float>(i,j);
}

如果数组非常大,您可能希望将这些移出循环:

cout.precision(1); 
cout.setw(5);

我更喜欢最后一种方法-因为它不会溢出,如果你的计算得到1210121281.9作为结果[你的布局将看起来有点滑稽]。

固定大小的缓冲区对我来说是一个警告信号。

作为故障排除步骤,更改

sprintf(buff, "%5.1f ", m.at<float>(i,j));

int const used = sprintf(buff, "%5.1f ", m.at<float>(i,j));
assert(used < 10);

除此之外,在那里使用动态分配显然是荒谬的。如果固定大小的缓冲区就足够了,只需使用本地自动数组变量即可。当你这样做的时候,堆栈空间是很便宜的,所以通过使缓冲区足够大来防止溢出。

void dumpFloatMatrix( Mat m )
{
    char buff[400];
    for(int i = 0; i < m.cols; i++){
        for(int j = 0; j < m.rows; j++){
            int const used = sprintf(buff, "%5.1f ", m.at<float>(i,j));
            assert(used * sizeof *buff < sizeof buff);
            cout << buff;
        }
        cout << endl;
    }
}