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 **&
?只要您执行*(scoreSet + i)
其中i > 0
您有未定义的行为。
我知道我一定没有正确分配指针,但我不确定在哪里。 -- 解释你在这里做什么:double *scores = nullptr; double **scoreSet = &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 时发生访问冲突
在 filePath.exe 中的 0x793F3729 (vcruntime140d.dll) 处引发异常:0xC0000005:访问冲突写入位置 0xCDCDCDCD
在项目 2017.1.exe 中的 0x0FDD053F (ucrtbased.dll) 处引发 bmp 文件异常错误:0xC0000005:访问冲突写入位置 0xCDCDCDCD