字符串数组C++的Segfault

Segfault with String array C++

本文关键字:Segfault C++ 数组 字符串      更新时间:2023-10-16

我用C编写了这个程序,在学习该语言时,我试图将一些程序转换为C++。基本上把数组的字符转换成字符串和一些输入/输出。唯一的问题是,当我试图将输入字符串放入字符串数组时,会出现segfault(test2打印。test3不打印)。

有什么想法吗?在学习c++的过程中,我应该注意哪些不好的编码习惯?

int main() {
int nstr=0, nchar=0, nint=0, nfloat=0;
string input;
int i, z=0;
float inputFloat;
string *strList = (string*)malloc(sizeof(string) * nstr);
char *charList = (char*)malloc(sizeof(char) * nchar);
int *intList = (int*)malloc(sizeof(int) * nint);
float *floatList = (float*)malloc(sizeof(float) * nfloat);
while (z != -42) {
    cout << "Input:  ";
    cin >> input;
    cin.ignore();
    inputFloat = strtof(input.c_str(), NULL);
    if (inputFloat) {
        if (fmod(inputFloat, 1.0)) {
            nfloat++;
            floatList = (float*)realloc(floatList, sizeof(float) * nfloat);
            floatList[nfloat-1] = inputFloat;
        }
        else {
            nint++;
            intList = (int*)realloc(intList, sizeof(int) * nint);
            intList[nint-1] = (int)inputFloat;
        }
    }
    else {
        if (input.length() == 1) {
            nchar++;
            charList = (char*)realloc(charList, sizeof(char) * nchar);
            if (input.at(0) == 10)
                input = " ";
            charList[nchar-1] = input.at(0);
        }
        else {
            nstr++;
            cout << "test1" << endl;
            strList = (string*)realloc(strList, sizeof(string) * nstr);
            cout << "test2" << endl;
            strList[nstr-1] = input;
            cout << "test3" << endl;
        }
    }
    cout << "Integers: ";
    for (i=0; i<nint; i++)
        cout << intList[i] << " ";
    cout << endl << "  Floats: ";
    for (i=0; i<nfloat; i++)
        cout << floatList[i] << " ";
    cout << endl << "   Chars: ";
    for (i=0; i<nchar; i++)
        cout << charList[i] << " ";
    cout << endl << " Strings: ";
    for (i=0; i<nstr; i++)
        cout << strList[i] << " ";
    cout << endl << endl;
}
}

通常,在c++中根本不使用malloccallocrealloc等,即使可以。它对int、char等简单项目没有太大意义,但当在对象(如std::string)上使用时,会导致以下问题:

当这条线路运行时:

string *strList = (string*)malloc(sizeof(string) * nstr);

您将存储分配给字符串数组,但并没有调用任何构造函数,因此您分配的所有存储仍然是无用的。

在c++中,您必须像这样使用new

string *strList = new string[nstr];

它更短、更容易,并调用每个分配对象的构造函数。

最后,你用delete []这样处理它:

delete [] strList;

更好的是使用:

vector<string> strList;

并使用添加元素:

strList.push_back("something");strList.push_back(some_string);

vector负责内存分配和释放,并在生命结束时作为常规对象自动释放,因此根本不需要删除。

realloc重新分配一个比上一个更大的数组。数组末尾的新元素,您可以将其填充为整数、float、char,这些都是基本的C类型。对于像字符串这样的C++对象,数组中的最后一个元素不是新字符串,其中一种可能性是创建字符串指针数组。

在代码的开头

string **strList = (string**)malloc(sizeof(string *) * nstr);

在代码结束时,在数组的末尾分配一个新的字符串对象。

nstr++;
strList = (string**)realloc(strList, sizeof(string *) * nstr);
strList[nstr-1] = new string(input);

在程序结束时,必须删除通过new操作符和malloc/realloc创建的所有内容。

while (nstr--)
{
   delete strList[nstr];
}
free(strList);