0xC0000005:访问冲突写入位置 0xCDCCDCD 动态分配错误

Posted

技术标签:

【中文标题】0xC0000005:访问冲突写入位置 0xCDCCDCD 动态分配错误【英文标题】:0xC0000005: Access violation writing location 0xCDCDCDCD Dynamic Allocation Error 【发布时间】:2020-01-27 21:26:40 【问题描述】:

获取 0xC0000005:使用以下代码写入位置 0xCDCDCDCD 的访问冲突。 我知道我一定没有正确分配指针,但我不确定在哪里。

我正在尝试让 **scoreSet 引用 *scores 的集合,而 *scores 将手动输入。指向数组的names 指针工作正常,并且似乎分配正确。问题是当我尝试为scoreSet 模仿相同的内容时,不同之处在于scoreSet 是指向指针数组scores 的指针。我觉得我试图动态分配这个指针指向的数组的方式是完全错误的。

基本上是在用户输入后尝试使这样的事情成为可能: scoreSet0 = 22,33,44 scoreSet1 = 35, 45, 65, 75 scoreSet3 = 10

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

int inputData(string*& names, double**& scores);

int main() 
    string *names = nullptr;
    double *scores = nullptr;
    double **scoreSet = &scores;
    int size = 0;
    size = inputData(names, scoreSet);
    for (int i = 0; i < size; i++) 
        cout << *(names+i) << endl;
    


int inputData(string*& names, double**& scoreSet) 
    int numStudents = 0;
    cout << "How many students do you have in the system? ";
    cin >> numStudents;
    while (numStudents <= 0) 
        cout << "Invalid number of students. Please enter number of students: ";
        cin >> numStudents;
    
    names = new string[numStudents];
    cin.ignore(10000, '\n');
    for (int i = 0; i < numStudents; i++) 
        int numTests = 0;
        cout << "Enter the student's name: ";
        getline(cin,names[i]);
        cout << "Enter how many tests " << *(names + i) << " took: ";
        cin >> numTests;
        *(scoreSet + i)= new double[numTests];                   //Pretty sure this is wrong.
        cin.ignore(10000, '\n');
        for (int j = 0; j < numTests; j++)                 //This loop is causing the error.
            cout << "Enter grade #" << j + 1 << ": ";
            cin >> *(scoreSet+i)[j];
        
    
    return numStudents;

【问题讨论】:

使用向量>. 有没有办法在不使用向量的情况下做到这一点? 有没有办法在不使用向量的情况下做到这一点? -- 创建自己的向量类。这样做你会学到更多,而不仅仅是在整个代码中调用new[] 并导致内存泄漏。 当这个变量实际上只是一个double * 时,你为什么要使用double **&amp;?只要您执行*(scoreSet + i) 其中i &gt; 0 您有未定义的行为。 我知道我一定没有正确分配指针,但我不确定在哪里。 -- 解释你在这里做什么:double *scores = nullptr; double **scoreSet = &amp;scores;。它对您有意义吗,或者您是否正在尝试任何希望代码有效的方法? 【参考方案1】:

根据 PaulMcKenzie 的建议,这就是它的滚动方式。使用模板对您来说可能有点多,但如果可以的话... 否则分别创建名称和分数容器。但是你有重复的代码需要维护。

我们的想法是让你所有的东西都保持某种秩序。请注意,现在内存管理由container 处理。

我放弃了处理std::cin 和分数,但你应该更容易将这些东西编码回来,而不会造成太多的麻烦。那样的话,不用std::cin开发,就是浪费时间。您应该编写以便您可以编辑和运行。

还有,要改掉using namespace std;的习惯,从长远来看会有所回报的。

#define DEV
template<typename T>
struct container 
    size_t size;
    T* ar;
    container(size_t size) :size(size) 
        ar = new T[size];
    
    ~container()  delete[]ar; 
    T& operator [](size_t pos)  return ar[pos]; 
;
using names_c = container<std::string>;
using scores_c = container<double>;

size_t inputData(names_c& names, scores_c& scores);

int main() 
    container<std::string> names(2);
    container<double> scoreSet(2);

    auto size = inputData(names, scoreSet);
    for (int i = 0; i < size; i++) 
        std::cout << names[i] << endl;
    


size_t inputData(names_c& names, scores_c& scores) 
#ifdef DEV
    size_t numStudents = 2;
    names[0] = "tom";
    names[1] = "mary";
#else
    //do your std::cin stuff
#endif
    return names.size;

我不打算去那里,但是。您可以扩展这个概念,以便在容器中拥有容器。更容易知道哪个学生的分数。

struct student_type 
    using scores_c = container<double>;
    std::string name;
    scores_c scores;
;
using student_c = container<student_type>;

【讨论】:

【参考方案2】:

我已获取您的代码,并对其进行了修改以使其正常工作。我已经删除了您的 cmets,并将 cmets 放在我更改的行上。

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

int inputData( string *&names, double **&scores );

int main() 
    string *names = nullptr;
    double **scores = nullptr; // Changed to double ** so it's "2D"
    // double **scoreSet = &score; // removed, this was unneeded and probably causing problems
    int size = 0;
    size = inputData( names, scores );
    for ( int i = 0; i < size; i++ ) 
        cout << *( names + i ) << endl;
    


int inputData( string *&names, double **&scoreSet ) 
    int numStudents = 0;
    cout << "How many students do you have in the system? ";
    cin >> numStudents;
    while ( numStudents <= 0 ) 
        cout << "Invalid number of students. Please enter number of students: ";
        cin >> numStudents;
    
    names = new string[numStudents];
    scoreSet = new double*[numStudents]; // allocate an array of pointers
    // cin.ignore( 10000, '\n' ); // Removed from here, placed inside loop
    for ( int i = 0; i < numStudents; i++ ) 
        cin.ignore( 10000, '\n' ); // placed here so that it always clears before getting the name
        int numTests = 0;
        cout << "Enter the student's name: ";
        getline( cin, names[i] );
        cout << "Enter how many tests " << names[i] << " took: "; // simplified
        cin >> numTests;
        scoreSet[i] = new double[numTests]; // simpliefied left hand side
        //cin.ignore( 10000, '\n' ); // not needed
        for ( int j = 0; j < numTests; j++ ) 
            cout << "Enter grade #" << j + 1 << ": ";
            cin >> scoreSet[i][j]; // simplified
        
    
    return numStudents;

【讨论】:

以上是关于0xC0000005:访问冲突写入位置 0xCDCCDCD 动态分配错误的主要内容,如果未能解决你的问题,请参考以下文章

C++:0xC0000005:访问冲突写入位置0x00000000

处有未经处理的异常:0xC0000005:写入位置0x00EFA000时发生访问冲突.

0xC0000005: 写入位置 0x0000000002450040 时发生访问冲突

写入位置0x00460000时发生访问冲突,这是啥原因?

在 filePath.exe 中的 0x793F3729 (vcruntime140d.dll) 处引发异常:0xC0000005:访问冲突写入位置 0xCDCDCDCD

在项目 2017.1.exe 中的 0x0FDD053F (ucrtbased.dll) 处引发 bmp 文件异常错误:0xC0000005:访问冲突写入位置 0xCDCDCDCD