在 C++ 中打印 char 字符串时,Linux Ubuntu 中 g++ 的分段错误,但 Windows 中 g++/MingW 的分段错误

Segmentation Fault with g++ in Linux Ubuntu, but not with g++/MingW in Windows, when printing a char string in C++

我有一个程序,它:

  1. 创建一个包含 3 个 char 指针的数组,char *z_str[3];
  2. 分配 char 类型的动态内存对象并将返回的指针分配给这些 char 指针。
  3. 提示用户输入字符串。
  4. 打印提供的字符串。

源代码:

#include <iostream>
using namespace std;

int main()
{
    char *z_str[3];
    int i;

    for(i = 0; i < 2; i++)
    {
        z_str[i] = new char [30];
        if(z_str[i] == NULL)
        {
            cout << "Memory for String " << i+1 << " could not be allocated!" << endl;
            cout << "Program terminates.";
            return 1;
        }
    }

    cout << endl << endl;

    cout << "Please input the first string [max.29 characters]:" << endl;
    cin >> z_str[0]; 
    cout << endl;

    cout << "Please input the second string [max.29 characters]:" << endl;
    cin >> z_str[1]; 
    cout << endl;

    cout << "Please input the third string [max.29 characters]:" << endl;
    cin >> z_str[2]; 
    cout << endl << endl;


    cout << "First string is:" << endl;
    cout << z_str[0] << endl << endl;

    cout << "Second string is" << endl;
    cout << z_str[1] << endl << endl;

    cout << "Third string is:" << endl;
    cout << z_str[2] << endl << endl;

    return 0;
}

当我在 Linux Ubuntu 和 运行 中使用 g++ 编译此代码时,当程序打印 [=16] 时出现分段错误=]字符串进入 CLI。

终端输出:

Please input the first string:
string1

Please input the second string:
string2

Please input the third string:
string3
Segmentation fault (core dumped)

现在,如果我在 Windows10 中使用 g++/MingW 编译相同的代码,那么在 PowerShell 中一切正常:


Please input the first string:
string1

Please input the second string:
string2

Please input the third string:
string3


First string is:
string1

Second string is
string2

Third string is:
string3

循环

for(i = 0; i < 2; i++)

会让你初始化z_str[0]z_str[1],但不会 z_str[2].

因此,当您在 z_str[2].

中使用未初始化和不确定的值时,您会得到未定义的行为(和崩溃)

您需要增加循环以遍历所有元素:

for(i = 0; i < 3; i++)

所有这些都有更好的解决方案,我推荐的是使用 std::array of std::string 对象:

std::array<std::string, 3> z_str;

现在你不需要自己做任何动态分配,数组中的所有三个字符串都将默认构造,这意味着它们将是空(但有效)字符串。

如果您既不被允许使用 std::array 也不被允许使用 std::string,还有其他方法可以改进您的程序,例如使用 range for loops:

for (auto& str_ptr : z_str)
    str_ptr = new char[30];

上面的循环保证遍历数组的所有元素。