我是C ++的新手,我遇到的这个问题让我在过去的2个小时里难以接受。我要做的是创建一个指向我的类Word对象的指针数组,这样一个二维数组,即**wordPtrList
。然后我需要删除数组中某些对象的内存并将其指针设置为null。我写了一个较小的版本,我想在下面完成。
int main()
{
char *cArray;
cArray = new char[4];
int i;
for (i = 0; i < 3; i++)
cArray[i] = 'a';
cArray[i + 1] = '\0'; //cArray is a null terminated string
Word **wordPtrList;
wordPtrList = new Word* [3];
for (i = 0; i < 3; i++)
{
wordPtrList[i] = new Word(cArray);
}
wordPtrList[1]->del();
delete wordPtrList[1];
wordPtrList[1] = '\0';
return 0;
}
class Word
{
private:
char* ptr_;
int len_;
public:
Word(const char* word)
{
len_ = strlen(word);
ptr_ = new char[len_];
strcpy(ptr_, word);
}
~Word()
{
delete [] ptr_;
ptr_ = 0;
}
void del()
{
delete [] ptr_;
ptr_ = 0;
return;
}
};
当我这样做时,我得到:
正常阻止后检测到的调试错误堆损坏
这是在Windows 7上的VS 2010中。
所以我要问的是,如何删除对象的内存以便将wordPtrList[1]
设置为Null?
答案 0 :(得分:2)
看看这段代码:
for (i = 0; i < 3; i++)
cArray[i] = 'a';
cArray[i + 1] = '\0'; //cArray is a null terminated string
问题出在使用i+1
作为索引的最后一行,它超出了范围,就像循环退出时一样,i
的值已经{{1} };这意味着3
将成为i+1
,当您将4
分配为:{/ p>时,cArray
无法成为有效索引
cArray = new char[4]; //taken from your code
解决方案是:
cArray[i] = '\0'; //Now, it is correct. Here i is equal to 3
即,使用i
代替i+1
;或者只使用3
。
在C ++中,你可以std::fill
而不是手动循环,如:
std::fill(cArray, cArray + 4, 'a'); //done
更好地避免尽可能使用char*
与new
,并且更喜欢使用std::string
。
答案 1 :(得分:2)
您正在为cArray分配4个字节(意味着您可以访问写入0到3的字节),然后写入cArray [4]。您还在Word构造函数中分配了一个太小的字节。
char *cArray;
cArray = new char[4];
int i;
for (i = 0; i < 3; i++)
cArray[i] = 'a';
cArray[i] = '\0'; //cArray is a null terminated string - i is now 3
和
Word(const char* word)
{
len_ = strlen(word);
ptr_ = new char[len_ + 1];
strcpy(ptr_, word);
}
应该这样做。
答案 2 :(得分:0)
代码中有两个明显的逐个错误(当你离开第一个循环时变量i
的值是什么?)当你调用strlen
时你是否记得考虑过null终止符所需的空间?)。
另请注意,c字符串不是“空终止”,它们是“NUL终止”,大写字母只有一个“L”。 NUL
是ASCII控制字符的名称,所有位都设置为零,并在C ++中用'\0'
表示。
在一个地方你使用NUL
字符作为空指针,虽然这在技术上是正确的(因为C ++语言的设计错误),但最好还是明白这两个概念是完全不同的。
答案 3 :(得分:0)
正如其他人所说,你基本上是在访问超出数组范围的数组索引。
我会选择Nathan Wiebe的解决方案。
将来,当您可以选择执行此操作时,建议使用std::vector<T>
,因为这样可以在动态可调整大小的数组中存储您希望的任何类型。换句话说,如果你不访问向量边界之外的索引,你可以这样做:
std::vector< char* > str;
for( size_t i = 0; i < str.size(); ++i )
{
str.push_back( 'a pointer to a block of memory consisting of characters' );
}
class Word
{
public:
Word( const char* str )
{
mStrs.push_back( str );
}
~Word( void )
{
for( size_t i = 0; i < mStrs.size(); ++i )
{
if( mStrs[ i ] )
{
delete mStrs[ i ];
mStrs[ i ] = NULL;
}
}
mStrs.clear();
}
private:
void del( size_t index )
{
if( index > mStrs.size() )
{
//error - throw new exception or something
}
delete mStrs[ index ];
}
std::vector< const char* > mStrs;
};