调整动态字符串数组的大小

Resizing dynamic string array

本文关键字:数组 动态 字符串 调整      更新时间:2023-10-16

我正在尝试调整动态分配的字符串数组的大小;下面是代码!

void resize_array() {
    size_t newSize = hash_array_length + 100;
    string* newArr = new string[newSize];
    fill_n(hash_array,newSize,"0"); //fills arrays with zeros
    memcpy( newArr, hash_array, hash_array_length * sizeof(string) );
    hash_array_length = newSize;
    delete [] hash_array;
    hash_array = newArr;
}

不幸的是,它不工作,并给出一个分割错误。知道为什么吗?这基本上是一个线性探测哈希表,其中元素插入到有0的地方,因此我使用fill_n来填充新创建的数组。请帮忙好吗?

memcpy( newArr, hash_array, hash_array_length * sizeof(string) );

这一行非常危险,std::string不是普通的旧数据类型,你不能确保memcpy可以正确地初始化它,这可能会导致未定义行为,c++(或编程)中最讨厌的行为之一。

此外,有一个更好的和更安全的(在大多数时候)解决方案来创建c++中的动态字符串数组,只需使用vector

//create a dynamic string array with newSize and initialize them with "0"
//in your case, I don't think you need to initialize it with "0"
std::vector<std::string> newArr(newSize, "0"); 

如果hash_array的类型与newArr(std::vector)相同复制的方法很简单。

c++ 98

std::copy(hash_array.begin(), hash_array.end(), newArr.begin());
c++ 11

std::copy(std::begin(hash_array), std::end(hash_array), std::begin(newArr));

最好把c++当作一门新语言来对待,它和c有太多不同的地方。此外,还有很多不错的免费IDE,比如code::blocks和QtCreatordevc++几乎是一个死项目。

如果你是c++新手,c++ primer 5是一本很好的入门书。

如果string实际上是std::string(即使它不是),那么这将崩溃。您正在创建一个新的字符串数组,在上面复制旧的字符串类,然后释放旧的字符串。但是,如果string类包含指向已分配内存的内部指针,这将导致double free,因为您所做的只是复制内部指针,而不是分配新的内存。

这样想;假设您有以下类:

class foo
{
    char* bar;
    foo() { bar = malloc(100); }
    ~foo() { free(bar);
};
foo* ptr1 = new foo;
foo* ptr2 = new foo;
memcpy(ptr2, ptr1, sizeof(foo*));
delete ptr1;

此时,ptr2->bar指向与ptr1->bar相同的内存,但是ptr1和它所持有的内存已经被释放

最好的解决方案是使用std::vector,因为它可以自动处理大小调整,您根本不需要担心复制数组。但是,如果您想坚持当前的方法,则需要将memcpy调用更改为以下内容:

for (int i = 0; i < hash_array_length; ++i)
{
    newArr[i] = hash_array[i];
}

不只是复制内存,这将调用类的复制构造函数,并对其内容进行适当的复制。

我怀疑罪魁祸首是memcpy呼叫。string是一个复杂的类型,它通过指针来管理char数组(就像你现在所做的那样)。通常复制string是使用赋值操作符完成的,对于string,赋值操作符也会复制它自己的数组。但是memcpy只是逐字节复制指针,delete[]也删除由string管理的数组。现在另一个字符串使用已删除的字符串数组,即BAAAD。

您可以使用std::copy来代替memcpy,或者更好的是,使用std::vector,这是解决大多数动态内存处理问题的方法。