动态初始化字符的 2D 数组时"Segmentation Fault [Core Dumped]"

"Segmentation Fault [Core Dumped]" while initializing 2d array of char dynamically

本文关键字:Fault Segmentation Core Dumped 字符 初始化 2D 数组 动态      更新时间:2023-10-16

我想从user获取一个字符串数组。我得到的例外"分割故障[核心转储]"在运行时。

#include <iostream>
#include <iomanip>
#include <math.h>
#include <string.h>
using namespace std;
int main() {
    long testCaseCount = 0;
    cin >> testCaseCount;
    char **testCases;
    *testCases = new char[testCaseCount];
    for(int i=0;i<testCaseCount;i++) {
        cin >> testCases[i];
    }
}

您没有为每个正在读取的字符串分配空间。下面是您正在尝试的两种方法,第一种是您似乎想采用的主要使用c的方法,第二种是充分利用标准库的所有优点。

下面的两个示例应该在给定相同输入内容的情况下产生相同的测试字符串。第一个会随着每个新的额外字符的到来而调整大小。虽然看起来有点矫枉过正,但它实际上比维护一个几何增长算法更简单。

也就是说,下面是代码。我让您来决定哪一个更容易出现错误和bug(我只是在网上写了这两个,所以无论如何肯定会有bug)。

#include <iostream>
#include <cstdlib>
#include <cctype>
using namespace std;
int main() 
{
    unsigned int testCaseCount = 0;
    char **testCases = NULL;
    // read and validate we received a count greater than zero
    if (cin >> testCaseCount && testCaseCount > 0)
    {
        // allocate + nullinitialize that many pointers
        testCases = new char *[testCaseCount]();
        for (unsigned int i = 0; i < testCaseCount && cin; ++i)
        {
            // skip leading whitespace
            char ch;
            while (cin.get(ch) && std::isspace(ch));
            if (cin)
            {
                // read chars until whitespace or EOF. vsize
                //  represents the size of the allocated buffer
                char *value = new char[1]();
                size_t vsize = 1;
                while (cin.get(ch) && !std::isspace(ch))
                {
                    // allocate larger buffer
                    char *tmp = new char[vsize + 1];
                    // copy in old content to new buffer
                    std::copy(value, value + vsize, tmp);
                    std::swap(value, tmp);
                    // save new char and terminator
                    value[vsize - 1] = ch;
                    value[vsize++] = 0;
                    // delete old buffer
                    delete[] tmp;
                }
                // save accumulated value.
                testCases[i] = value;
            }
        }
    }
    // show test cases
    for (unsigned int i = 0; i < testCaseCount && testCases[i]; ++i)
        std::cout << testCases[i] << 'n';
    // cleanup
    for (unsigned int i = 0; i < testCaseCount && testCases[i]; ++i)
        delete[] testCases[i];
    delete[] testCases;
    return 0;
}

#include <iostream>
#include <iterator>
#include <vector>
#include <string>
int main()
{
    unsigned int testCaseCount = 0;
    std::vector<std::string> testCases;
    if (cin >> testCaseCount)
    {
        std::string s;
        while (testCaseCount-- && cin >> s)
            testCases.emplace_back(s);
    }
    // show test cases
    for (auto const& s : testCases)
        std::cout << s << 'n';
    return 0;
}

你必须至少写为

char **testCases = new char *;
*testCases = new char[testCaseCount];

虽然不清楚为什么你不想简单地写成

char *testCases = new char[testCaseCount];

并且不要忘记删除用new操作符分配的内容。

请注意它不是"字符串数组"。它只是一个字符数组。如果你想得到一个字符串数组,你应该首先决定字符串的最大长度。

首先需要为每个字符串的第一个字符的指针分配空间:

char** testCases = new char*[testCaseCount];

那么你需要为每个字符串分配空间:

testCaseCount[i] = new char[maxStringLength];
cin >> testCaseCount[i];

然而,这是危险的——cin不会做任何边界检查。你真的应该使用std::string.

运行时异常"Segmentation Fault [Core dumps] .

通过解引用:

中的未定义指针来实现未定义行为。
*testCases = new char[testCaseCount];

目标:我想从用户

中获得字符串数组

在c++中使用std::stringstd::vector:

#include <iostream>
#include <string>
#include <vector>
int main() {
    long testCaseCount = 0;
    std::cin >> testCaseCount;
    std::vector<std::string> testCases(testCaseCount);
    for (auto& s : testCases)
        std::cin >> s;
}

现场演示

相关文章: