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

时间:2013-03-31 20:59:36

标签: c++ arrays resize

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

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用0填充新创建的数组。有什么帮助吗?

3 个答案:

答案 0 :(得分:4)

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和QtCreator devc ++几乎已经死了。

如果您不熟悉c ++,那么c ++ primer 5是一本很好的书。

答案 1 :(得分:1)

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

这样想;想象你有以下课程:

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];
}

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

答案 2 :(得分:0)

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

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