字符串数组 C++ 的段错误
Segfault with String array C++
这个程序是用 C 语言编写的,在我学习这门语言的过程中正试图将一些程序转换为 C++。基本上是char数组到字符串和一些input/output。唯一的问题是我在尝试将输入字符串放入字符串数组时出现段错误(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;
}
}
realloc 重新分配一个比前一个更大的数组。数组末尾的新元素,你把它填成整数、浮点数、字符,这些都是基本的 C 类型。对于像字符串这样的 C++ 对象,数组中的最后一个元素不是新字符串,一种可能性是创建字符串指针数组。
在代码的开头
string **strList = (string**)malloc(sizeof(string *) * nstr);
并在代码末尾,在数组末尾分配一个新的字符串对象。
nstr++;
strList = (string**)realloc(strList, sizeof(string *) * nstr);
strList[nstr-1] = new string(input);
在程序结束时,您必须删除通过新运算符和 malloc/realloc 创建的所有内容。
while (nstr--)
{
delete strList[nstr];
}
free(strList);
作为一条规则,你根本不会在 c++ 中使用 malloc
、calloc
、realloc
等,即使你可以。
它对像 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
s 负责内存分配和释放,并在生命周期结束时作为常规对象自动释放,因此根本不需要删除。
这个程序是用 C 语言编写的,在我学习这门语言的过程中正试图将一些程序转换为 C++。基本上是char数组到字符串和一些input/output。唯一的问题是我在尝试将输入字符串放入字符串数组时出现段错误(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;
}
}
realloc 重新分配一个比前一个更大的数组。数组末尾的新元素,你把它填成整数、浮点数、字符,这些都是基本的 C 类型。对于像字符串这样的 C++ 对象,数组中的最后一个元素不是新字符串,一种可能性是创建字符串指针数组。
在代码的开头
string **strList = (string**)malloc(sizeof(string *) * nstr);
并在代码末尾,在数组末尾分配一个新的字符串对象。
nstr++;
strList = (string**)realloc(strList, sizeof(string *) * nstr);
strList[nstr-1] = new string(input);
在程序结束时,您必须删除通过新运算符和 malloc/realloc 创建的所有内容。
while (nstr--)
{
delete strList[nstr];
}
free(strList);
作为一条规则,你根本不会在 c++ 中使用 malloc
、calloc
、realloc
等,即使你可以。
它对像 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
s 负责内存分配和释放,并在生命周期结束时作为常规对象自动释放,因此根本不需要删除。