C++ 数组调整大小崩溃
C++ Array Resize crash
我有一个使用模板并具有大小的简单数组 class。我想在它满了的时候调整它的大小,但我的程序总是崩溃。
代码是这样的:
template<class T>
class Buffer:public File_ptr
{
unsigned int siz;
T *data;
public:
///konstruktor(size,filename,openmode)
Buffer(unsigned int s=50,const char* n, const char* m):File_ptr(n,m),siz(s)
{
data= new T[siz];
for(unsigned int i=0; i<siz; ++i)
{
data[i]=0;
};
};
///destruktor
~Buffer()
{
delete[] data;
}
///operator[]
T& operator[](unsigned int i)
{
if(i>siz)
{
unsigned int newsize=siz*2;
T* tmp=new T[newsize];
for(unsigned int j = 0; j < siz; j++)
{
tmp[j] = data[j];
}
siz=newsize;
delete[] data;
data=tmp;
delete[] tmp;
};
return data[i];
}
};
操作符[]出错了。(至少我认为是这样)。
主程序是这样的:
int main()
{
Buffer<int> k(20,"k.txt","w");
Buffer<char*> s(20,"s.txt","w");
k.printfile("HEY");
s.printfile(5);
for(unsigned int i=0;i<23;i++){
s[i]="Hey";
cout << s[i] << endl;
}
return 0;
}
任何帮助都会很棒! :)
谢谢!
您遇到了分段错误,因为您删除了两次内存。
data=tmp;
delete[] tmp;
在这里,您将 data
分配给 tmp
的内存位置。到目前为止一切顺利,data
和 tmp
指向同一个内存区域。但是现在你delete[] temp;
,所以内存区域被删除了。但是因为 data
也指向它,所以 data
也不再有效用作指针(如 tmp
)。
然后,return data[i];
你试图访问那段记忆,但你删除了它!所以你得到了一个分段错误。
你可以通过 not delete[] tmp;
来解决这个问题,因为 data
指向一个有效的内存位置,一切都很好 :)
您删除了 operator[]
中 tmp
仍然引用的新数组。由于这是 data
引用的新数组,您不可避免地 运行 会遇到麻烦。
你有几个问题。第一个问题是您删除了 tmp
指向的内存,这也是 data
现在指向的内存。这意味着下次数组增长时,您将访问一个已删除的指针,这是未定义的行为。
第二个问题是 if(i>siz)
检查 i
是否超过了数组的末尾,但您永远不会检查 i
是否也大于 newsize
。您需要将 newsize
设置为 siz * 2
和 i
中的最大值。 operator[] 增长容器也是不直观的。当您调用 []
的大小大于容器的大小时,这应该是一个错误,而不是重新调整数组的大小。
我有一个使用模板并具有大小的简单数组 class。我想在它满了的时候调整它的大小,但我的程序总是崩溃。 代码是这样的:
template<class T>
class Buffer:public File_ptr
{
unsigned int siz;
T *data;
public:
///konstruktor(size,filename,openmode)
Buffer(unsigned int s=50,const char* n, const char* m):File_ptr(n,m),siz(s)
{
data= new T[siz];
for(unsigned int i=0; i<siz; ++i)
{
data[i]=0;
};
};
///destruktor
~Buffer()
{
delete[] data;
}
///operator[]
T& operator[](unsigned int i)
{
if(i>siz)
{
unsigned int newsize=siz*2;
T* tmp=new T[newsize];
for(unsigned int j = 0; j < siz; j++)
{
tmp[j] = data[j];
}
siz=newsize;
delete[] data;
data=tmp;
delete[] tmp;
};
return data[i];
}
};
操作符[]出错了。(至少我认为是这样)。 主程序是这样的:
int main()
{
Buffer<int> k(20,"k.txt","w");
Buffer<char*> s(20,"s.txt","w");
k.printfile("HEY");
s.printfile(5);
for(unsigned int i=0;i<23;i++){
s[i]="Hey";
cout << s[i] << endl;
}
return 0;
}
任何帮助都会很棒! :) 谢谢!
您遇到了分段错误,因为您删除了两次内存。
data=tmp;
delete[] tmp;
在这里,您将 data
分配给 tmp
的内存位置。到目前为止一切顺利,data
和 tmp
指向同一个内存区域。但是现在你delete[] temp;
,所以内存区域被删除了。但是因为 data
也指向它,所以 data
也不再有效用作指针(如 tmp
)。
然后,return data[i];
你试图访问那段记忆,但你删除了它!所以你得到了一个分段错误。
你可以通过 not delete[] tmp;
来解决这个问题,因为 data
指向一个有效的内存位置,一切都很好 :)
您删除了 operator[]
中 tmp
仍然引用的新数组。由于这是 data
引用的新数组,您不可避免地 运行 会遇到麻烦。
你有几个问题。第一个问题是您删除了 tmp
指向的内存,这也是 data
现在指向的内存。这意味着下次数组增长时,您将访问一个已删除的指针,这是未定义的行为。
第二个问题是 if(i>siz)
检查 i
是否超过了数组的末尾,但您永远不会检查 i
是否也大于 newsize
。您需要将 newsize
设置为 siz * 2
和 i
中的最大值。 operator[] 增长容器也是不直观的。当您调用 []
的大小大于容器的大小时,这应该是一个错误,而不是重新调整数组的大小。