读取文件int struct时的STATUS_ACCESS_VIOLATION

时间:2012-02-23 22:25:36

标签: c++ struct

我正在读取结构中的3件事歌曲:歌曲,艺术家,文件大小。我运行程序时遇到错误,看起来是正确的。

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;

struct Songs
{
    string title;
    string artist;
    int size;
};

int main ()
{
    int num_songs;

    Songs song[num_songs];

    ifstream fin;
    fin.open("songlist.txt")

    while (fin.good()) {
        fin >> song[num_songs].title;
        fin >> song[num_songs].artist;
        fin >> song[num_songs].size;
        num_songs++;
    }
    fin.close();

    cout << "welcome to the show" << endl;
    return 0;
}

为什么程序在将文件读入STATUS_ACCESS_VIOLATION

时会产生struct

4 个答案:

答案 0 :(得分:4)

你的程序“看起来不正确”,它有很多错误,详见其他答案。

这是一个正确读入歌曲列表的程序。请注意,这些是用于读取文件的四种替代方法。选择对你最有意义的一个并删除其他三个。

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>

struct Song
{
    std::string title;
    std::string artist;
    int size;
    Song() : size() { }
    Song(const Song& song) :
      title(song.title), artist(song.artist), size(song.size) { }
    Song(std::string title, std::string artist, int size) :
      title(title), artist(artist), size(size) { }
};

std::istream&
operator>>(std::istream& is, Song& song) {
    return is >> song.title >> song.artist >> song.size;
}

int main ()
{    
   std::vector< Song > songs;

   std::ifstream fin;
   fin.open("songlist.txt");

   // You could read the songs this way:
   std::copy(std::istream_iterator<Song>(fin),
       std::istream_iterator<Song>(),
       std::back_inserter(songs));

   // Or, if you don't like std::copy, you can do this:
   Song song;
   while(fin >> song)
       songs.push_back(song);

   // Or, if you don't like operator>>(istream, Song), you can do this:
   std::string artist;
   std::string title;
   int size;
   while(fin >> artist >> title >> size)
       songs.push_back(Song(artist, title, size));

   // Or, if you don't like using the constructor:
   while(fin >> artist >> title >> size) {
       Song song;
       song.artist = artist;
       song.title = title;
       song.size = size;
       songs.push_back(song);
    }


    int num_songs = songs.size();
    std::cout << "welcome to the show: " << num_songs << "\n";
    return 0;
}

答案 1 :(得分:1)

你的代码非常疯狂......“歌曲”阵列有多大?目前,您将其初始化为“未定义”大小。你必须在num_songs initalise。没有这样做意味着它“可以”使用任何价值。您正在获取访问冲突,因为您将数组初始化为num_songs大小(我们将以任意数字70为例,尽管它可以是字面上的任何数字)然后您开始以相同的值写入数组(这是超过数组的结尾)。这是一种访问冲突,因为您随后会遇到您的进程不拥有的内存。因此,您通过尝试使用 access 的内存来违反内存空间。

您需要将其初始化为已知大小,以便您可以解析文件并找出其中有多少首歌曲。然后初始化你的数组,然后填充它。

使用stl向量会好得多,如下所示:

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>

using namespace std;

struct Songs
{
    string title;
    string artist;
    int size;

    Songs() {};
};

int main ()
{    
   std::vector< Songs > song;

   ifstream fin;
   fin.open("songlist.txt")

   while (fin.good()) 
   {
       song.push_back( Songs() );
       fin >> song.back().title;
       fin >> song.back().artist;
       fin >> song.back().size;
   }
   fin.close();

   int num_songs = song.size();

   cout << "welcome to the show" << endl;
   return 0;
}

答案 2 :(得分:1)

Songs song[num_songs]; num_songs的初始化在哪里?

答案 3 :(得分:0)

你有这个:

int num_songs;

Songs song[num_songs];

这不是合法的C ++。数组大小需要是编译时常量表达式。

GNU编译器有一个允许它的扩展,但即使在GNU中,用于定义数组大小的变量值也需要有一个定义的值。

当您写入具有未定义大小的数组时,您最终会到达内存中您不允许写入的位置,或者覆盖某些内存并更改程序中其他内容的含义。访问冲突是对这种情况的完全合法的回应。

您应该使用C ++容器,例如矢量,列表或双端队列。它们可以动态增长,以适应您文件中的许多项目。