当调用函数时,进程终止

时间:2021-05-20 21:01:41

I'm trying to write a function that will read and print the contents of a file. I gave the filename as a parameter for my function. I used FILE *testfile to create a file handle and then I use fread to read the file. block_t is a struct and nreserved are the reserved segments of the block. Each block has records. I don't think that it is necessary to tell you how block_t is created.

我正在尝试编写一个能够读取和打印文件内容的函数。我把文件名作为我的函数的参数。我使用FILE * testfile创建文件句柄然后使用fread来读取文件。 block_t是一个struct,nreserved是块的保留段。每个块都有记录。我认为没有必要告诉你block_t是如何创建的。

My problem is that even though the function runs and I can see in the console the results that I want to see the process terminates. This happens even if I comment out the if else parts. I get this message Process terminated with status -1073741510

我的问题是,即使该函数运行,我可以在控制台中看到我想看到该过程终止的结果。即使我注释掉了if else部分,也会发生这种情况。我收到此消息流程终止,状态为-1073741510

Here is my code:

这是我的代码:

#include "dbtproj.h"
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>

using namespace std;

void showEntriesOfBlock(char *filename){
    FILE *testfile;
    block_t block;
    int nreserved;


    //open file and print contents
    testfile = fopen(filename,"r");

    if(testfile==NULL)
        cout << "Error";
    else{
        while(!feof(testfile)){
            fread(&block, 1, sizeof(block_t), testfile);
            nreserved = block.nreserved;

    //print block contents
    for (int i=0; i<nreserved; ++i) {
        printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
                block.blockid, block.entries[i].recid, block.entries[i].num,
                block.entries[i].str);
        }
    }
}
fclose(testfile);
};

In my main file I create a file by using outfile = fopen("file.bin", "w"); then I write random data to the file. Then I close the file with fclose(outfile); and in the next line I call my function like this showEntriesOfBlock("file.bin");

在我的主文件中,我使用outfile = fopen(“file.bin”,“w”)创建一个文件;然后我将随机数据写入文件。然后我用fclose(outfile)关闭文件;在下一行我调用我的函数就像这个showEntriesOfBlock(“file.bin”);

Can anybody help? I think that I might have messed up my pointers of did something wrong with the file handlers.

有人可以帮忙吗?我想我可能搞砸了我对文件处理程序做错了什么的指示。

This is how I give data to my blocks and records.

这就是我向块和记录提供数据的方式。

for (int b=0; b<nblocks; ++b) { // for each block

    block.blockid = b;
    for (int r=0; r<MAX_RECORDS_PER_BLOCK; ++r) { // for each record

        // prepare a record
        record.recid = recid++;
        record.num = rand() % 1000;
        strcpy(record.str,"hello");   // put the same string to all records
        record.valid = true;

        memcpy(&block.entries[r], &record, sizeof(record_t)); // copy record to block
    }

    block.nreserved = MAX_RECORDS_PER_BLOCK;
    block.valid = true;

    fwrite(&block, 1, sizeof(block_t), outfile);    // write the block to the file
}

fclose(outfile);

And here are the definitions of my structs:

以下是我的结构的定义:

// This is the definition of a record of the input file. Contains three fields, recid,           num and str
typedef struct {
    unsigned int recid;
    unsigned int num;
    char str[STR_LENGTH];
    bool valid;  // if set, then this record is valid
 } record_t;


// This is the definition of a block, which contains a number of fixed-sized records
typedef struct {
    unsigned int blockid;
    unsigned int nreserved; // how many reserved entries
    record_t entries[MAX_RECORDS_PER_BLOCK]; // array of records
    bool valid;  // if set, then this block is valid
    unsigned char misc;
    unsigned int next_blockid;
    unsigned int dummy;
} block_t;

2 个解决方案

#1


1  

Here's a working version using FILE* (which I wouldn't recommend if you're learning...)

这是使用FILE *的工作版本(如果你正在学习,我不推荐......)

NOTE: open your files in binary mode : fopen(filename, "wb") or fopen(filename, "rb")

注意:以二进制模式打开文件:fopen(filename,“wb”)或fopen(filename,“rb”)

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cassert>
#include <fstream>

const int STR_LENGTH = 10;
const int MAX_RECORDS_PER_BLOCK = 5;

//! For my test I assumed the following definitions.
//! (i.e. that block_t is a POD.)
// This is the definition of a record of the input file. Contains three fields, recid,           num and str
typedef struct
{
    unsigned int recid;
    unsigned int num;
    char str[STR_LENGTH];
    bool valid;  // if set, then this record is valid
} record_t;


// This is the definition of a block, which contains a number of fixed-sized records
typedef struct 
{
    unsigned int blockid;
    unsigned int nreserved; // how many reserved entries
    record_t entries[MAX_RECORDS_PER_BLOCK]; // array of records
    bool valid;  // if set, then this block is valid
    unsigned char misc;
    unsigned int next_blockid;
    unsigned int dummy;
} block_t;

void showEntriesOfBlock(const char *filename)
{
    FILE* testfile = fopen(filename, "rb");
    assert(testfile);

    if (!testfile)
    {
        perror("Error");
        return;
    }

    block_t block;                
    while(fread(reinterpret_cast<char*>(&block), sizeof(block_t), 1, testfile))
    {
        if (ferror(testfile))
        {
            perror("Error while reading");
            return;
        }

        //print block contents
        for (int i = 0; i < block.nreserved; ++i)
        {
            printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
                block.blockid, block.entries[i].recid, block.entries[i].num,
                block.entries[i].str);
        }
    }

    fclose(testfile);
};

int main(int argc, const char *argv[])
{
    std::string filename = "g:/test.dat";
    FILE* outfile;
    outfile = fopen(filename.c_str(), "wb");
    int nblocks = 10;
    int recid = 0;

    for (int b = 0; b < nblocks; ++b)
    {
        block_t block;
        block.blockid = b;
        for (int r = 0; r < MAX_RECORDS_PER_BLOCK; ++r)
        {
            // for each record
            // prepare a record
            record_t record;
            record.recid = recid++;
            record.num = rand() % 1000;
            strcpy(record.str, "hello");   // put the same string to all records
            record.valid = true;

            memcpy(&block.entries[r], &record, sizeof(record_t)); // copy record to block
        }

        block.nreserved = MAX_RECORDS_PER_BLOCK;
        block.valid = true;

        fwrite(&block, sizeof(block_t), 1, outfile);    // write the block to the file
    }

    fclose(outfile);

    showEntriesOfBlock(filename.c_str());

    return 0;
}

#2


0  

Try this:

尝试这个:

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cassert>
#include <fstream>
#include <type_traits>

void showEntriesOfBlock(char *filename)
{
    std::ifstream testfile(filename, std::ios_base::binary);
    assert(testfile);

    if (!testfile)
    {
        std::cout << "Error";
        return;
    }

    block_t block;
    int nreserved;

    while (testfile)
    {
        //! This assumes block is a POD.
        static_assert(std::is_pod<block_t>::value, "block_t is not a POD.");
        testfile.read(reinterpret_cast<char*>(&block), sizeof(block_t));
        nreserved = block.nreserved;

        //print block contents
        for (int i = 0; i < nreserved; ++i) 
        {
            printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
                    block.blockid, block.entries[i].recid, block.entries[i].num,
                    block.entries[i].str);
        }        
    }

    testfile.close();
};

#1


1  

Here's a working version using FILE* (which I wouldn't recommend if you're learning...)

这是使用FILE *的工作版本(如果你正在学习,我不推荐......)

NOTE: open your files in binary mode : fopen(filename, "wb") or fopen(filename, "rb")

注意:以二进制模式打开文件:fopen(filename,“wb”)或fopen(filename,“rb”)

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cassert>
#include <fstream>

const int STR_LENGTH = 10;
const int MAX_RECORDS_PER_BLOCK = 5;

//! For my test I assumed the following definitions.
//! (i.e. that block_t is a POD.)
// This is the definition of a record of the input file. Contains three fields, recid,           num and str
typedef struct
{
    unsigned int recid;
    unsigned int num;
    char str[STR_LENGTH];
    bool valid;  // if set, then this record is valid
} record_t;


// This is the definition of a block, which contains a number of fixed-sized records
typedef struct 
{
    unsigned int blockid;
    unsigned int nreserved; // how many reserved entries
    record_t entries[MAX_RECORDS_PER_BLOCK]; // array of records
    bool valid;  // if set, then this block is valid
    unsigned char misc;
    unsigned int next_blockid;
    unsigned int dummy;
} block_t;

void showEntriesOfBlock(const char *filename)
{
    FILE* testfile = fopen(filename, "rb");
    assert(testfile);

    if (!testfile)
    {
        perror("Error");
        return;
    }

    block_t block;                
    while(fread(reinterpret_cast<char*>(&block), sizeof(block_t), 1, testfile))
    {
        if (ferror(testfile))
        {
            perror("Error while reading");
            return;
        }

        //print block contents
        for (int i = 0; i < block.nreserved; ++i)
        {
            printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
                block.blockid, block.entries[i].recid, block.entries[i].num,
                block.entries[i].str);
        }
    }

    fclose(testfile);
};

int main(int argc, const char *argv[])
{
    std::string filename = "g:/test.dat";
    FILE* outfile;
    outfile = fopen(filename.c_str(), "wb");
    int nblocks = 10;
    int recid = 0;

    for (int b = 0; b < nblocks; ++b)
    {
        block_t block;
        block.blockid = b;
        for (int r = 0; r < MAX_RECORDS_PER_BLOCK; ++r)
        {
            // for each record
            // prepare a record
            record_t record;
            record.recid = recid++;
            record.num = rand() % 1000;
            strcpy(record.str, "hello");   // put the same string to all records
            record.valid = true;

            memcpy(&block.entries[r], &record, sizeof(record_t)); // copy record to block
        }

        block.nreserved = MAX_RECORDS_PER_BLOCK;
        block.valid = true;

        fwrite(&block, sizeof(block_t), 1, outfile);    // write the block to the file
    }

    fclose(outfile);

    showEntriesOfBlock(filename.c_str());

    return 0;
}

#2


0  

Try this:

尝试这个:

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cassert>
#include <fstream>
#include <type_traits>

void showEntriesOfBlock(char *filename)
{
    std::ifstream testfile(filename, std::ios_base::binary);
    assert(testfile);

    if (!testfile)
    {
        std::cout << "Error";
        return;
    }

    block_t block;
    int nreserved;

    while (testfile)
    {
        //! This assumes block is a POD.
        static_assert(std::is_pod<block_t>::value, "block_t is not a POD.");
        testfile.read(reinterpret_cast<char*>(&block), sizeof(block_t));
        nreserved = block.nreserved;

        //print block contents
        for (int i = 0; i < nreserved; ++i) 
        {
            printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
                    block.blockid, block.entries[i].recid, block.entries[i].num,
                    block.entries[i].str);
        }        
    }

    testfile.close();
};