我正在尝试创建一个类似于C ++中内置向量类的类。我试图遵循Walter Savitche的教科书中的所有说明,但却无法让它正常工作。
代码是使用Code :: Blocks IDE编写的,并使用gcc编译器编译。
我认为我缺少的是数组参数和指向数组的指针之间的关系。 这是我对正常变量的理解:
int *p1, *p2, *p3, *p4, a;
a = 5; // variable of type int with value 5
p1 = &a; // p1 now points to the value 5
p2 = p1; // p2 now also points to the value of a
p3 = new int; // p3 points to an anonamous variable of type int with undefined value
*p3 = *p1 // value of variable changed to the value of a, namely 5, but doesn't point to a
p4 = new int; // p4 points to an anonamous variable of type int with undefined value
*p4 = 5; // value of variable changed to 5
p4 = p1 // p4 now also points to the value of a
这是我基本上不了解指向数组的数组和指针
int *p1, *p2, *p3, *p4, a[3] = {4, 5, 6}; // a points to the first indexed element of the array, namely 4
p1 = a; // p1 points to the exactly the same thing as a
p2 = new int[3]; // p2 points to an array of base type int with undefined values
p2[0] = 8; // is this the correct usage? is p2 "dereferenced"
p2[1] = 9;
p2[2] = 10;
p2[2] = p1[2]; // again is this correct? is the third element of the array pointed to by p2 now equal to 6?
*p3 = a // what does this mean?
p4 = new int[4]; // p4 points to an array of base type int with undefined values
p4[0] = p2[0];
p4[1] = p2[1];
p4[2] = p2[2];
p4[3] = 3
p2 = p4 // p2 now points to p4, but what happens to the array p2 was pointing to?
delete [] p2; // does this destroy the pointer and the array it is pointing to or just one or the other?
为了完整起见,我的课程定义如下:
class VectorDouble
{
public:
// constructors
VectorDouble(); // default constructor
VectorDouble(int init_count); // user specified
VectorDouble(const VectorDouble& vd_object); // copy constructor
// destructor
~VectorDouble();
// accessors
int capacity_vd(); // get max_count
int size_vd(); // get amt_count
double value_at(int index); // get value of "value" at index i
// mutators
void push_back_vd(double put_at_end); // insert new element at end of "value"
void reserve_vd(int incr_capacity); // set max_count
void resize_vd(int incr_size); // set amt_count
void change_value_at(double d, int index); // set value of "value" at index i
// overloaded =
void operator =(const VectorDouble& vd_object_rhs);
// other
friend bool operator ==(VectorDouble vd_object1, VectorDouble vd_object2);
private:
double *value; // pointer that points to array of type double
int max_count; // the memory allocated to the array
int amt_count; // the amount of memory in use
};
麻烦的功能是:
void VectorDouble::push_back_vd(double put_at_end)
{
double *temp;
if(amt_count == max_count)
max_count += 1;
temp = new double[max_count];
for(int i = 0; i < amt_count; i++)
temp[i] = value[i];
amt_count += 1;
temp[amt_count] = put_at_end;
value = temp;
}
成员函数似乎只是插入0.0而不是用户输入,我不知道为什么......
主要:
VectorDouble vec1(10);
double dd;
cout << "Enter 3 doubles to vec1:\n";
for(int i = 0; i < 3; i++)
{
cout << i << ": ";
cin >> dd;
vec1.push_back_vd(dd);
}
cout << "The variables you entered were:\n";
for(int i = 0; i < 3; i++)
cout << i << ": " << vec1.value_at(i) << endl;
我输入:
12.5 16.8 15.2
我回来了:
0 0 0
我修好了!唯一的问题是错误非常简单。很抱歉浪费每一个人的时间,但多亏了所有,我确实学到了很多东西!
错误是我放置amt_count += 1;
,我习惯于从1开始索引的数组而不是零(我在R语言中做了很多编码)。纠正密码泄漏的纠正代码是:
void VectorDouble::push_back_vd(double put_at_end)
{
double *temp;
if(amt_count == max_count)
max_count += 1;
temp = new double[max_count];
for(int i = 0; i < amt_count; i++)
temp[i] = value[i];
temp[amt_count] = put_at_end;
amt_count += 1;
delete [] value;
value = temp;
}
答案 0 :(得分:1)
这是我对正常变量的理解
一切都正确,但需要注意的是我要避免使用术语“指向值 x ”;您指向对象,而对象又具有值 x 。
这是我基本上不了解指向数组的数组和指针
你把指针与数组混淆了。在int a[3]
中,a
是一个数组。它不是指针。这是一个数组。
*p3 = a
无效,所以没有任何意义。
p2现在指向p4,但是数组p2发生了什么指向?
你已经泄露了它。
//这是否会破坏指针及其指向的数组或只是其中一个?
它会摧毁指针所指向的new
'。即阵列
否则一切正确。
至于你的矢量实现,主要问题是temp[amt_count]
是一个溢出因为你已经增加了amt_count
。此外,矢量实现通常以指数方式而非按需方式增长。最后,你正在泄漏以前的存储空间。
答案 1 :(得分:1)
使用不同的术语可能会对您有所帮助:
指针只是一个普通变量。它不包含整数,浮点数,双精度等,而是保存内存地址。请考虑以下事项:
int* p = nullptr; // p has the value "nullptr" or null memory address
int i = 5; // i has value 5
p = &i; // p now has the value of the address of i
&符号获取变量的地址。
星号取消引用指针;也就是说,它将获得存储在指针所占用的内存地址中的值:
cout << *p << endl; // Prints whatever is stored in the memory address of i; 5
对于矢量实现,请尝试将此行amt_count += 1;
移到此行下方:
temp[amt_count] = put_at_end;
,因为您尝试访问数组末尾。
a[3] = {4, 5, 6}; // a points to the first indexed element of the array, namely 4
尽管可以以类似的方式对数组和指针进行索引和处理,但它们是不同的,它们之间的差异可能导致一些偷偷摸摸的错误;所以要小心这句话。
*p3 = a // what does this mean?
这是无效的。您的类型不匹配:* p3是整数,a是数组。
p2 = p4 // p2 now points to p4, but what happens to the array p2 was pointing to?
数组p2指向的是现在泄露的内存。这很糟糕。
delete [] p2; // does this destroy the pointer and the array it is pointing to or just one or the other?
指针的值不会改变。但是,它指向的内存已被释放,因此取消引用它将为您提供未定义的结果。删除后最好设置p2 = nullptr;
。
This answer可能有助于您理解数组并访问其元素。
答案 2 :(得分:0)
你的功能真的错了......
void VectorDouble::push_back_vd(double put_at_end)
{
double *temp;
if(amt_count == max_count)
max_count += 1;
temp = new double[max_count];
for(int i = 0; i < amt_count; i++)
temp[i] = value[i];
amt_count += 1;
temp[amt_count] = put_at_end;
value = temp;
}
请注意,在每次调用中,您都会分配新数组(即使还有空格),复制其中的所有内容并泄漏内存(旧数组)......
这是一个略微更正的版本,但不能保证完全没问题(;
void VectorDouble::push_back_vd(double put_at_end)
{
if(amt_count == max_count)
{
max_count += 1;
double *temp = new double[max_count];
for(int i = 0; i < amt_count; i++)
temp[i] = value[i];
delete[] value;
value = temp;
}
value[amt_count] = put_at_end;
amt_count += 1;
}
答案 3 :(得分:0)
“p2现在指向p4,但是数组p2发生了什么指向?”
它已“泄露”,这意味着它仍然已分配,但无法再进入它。如果你继续这样做是同一个程序你的内存大小将继续增长
其他语言(Java,c#,...)有'垃圾收集器',可以检测何时发生这种情况并自动释放内存
这个问题的C ++解决方案是永远不会使用裸数组和指针。相反,你使用std :: vector和std :: shared_ptr;这些将为你清理