"分段错误[Core Dumped]"同时初始化动态的2d数组char

时间:2014-06-05 18:35:02

标签: c++

我想从用户那里获得一个字符串数组。我收到异常"分段错误[核心转储]"在运行时。

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

4 个答案:

答案 0 :(得分:3)

您没有为每个正在读取的字符串分配空间。以下是两种方法来做你正在尝试的事情,第一种是你似乎想要采用的大多数C方法,第二种是充分利用标准库来实现它的所有荣耀。

以下两个示例都应该在给定相同输入内容的情况下生成相同的测试字符串。第一个调整大小,每个新的额外字符到达。虽然它看起来有些过分,但它实际上比维护几何增长算法更简单。

那说,这是代码。我留给你来决定哪一个更容易出错和错误(我刚刚在网上写过,所以无论如何都会有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;
}

答案 1 :(得分:2)

你必须写至少为

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

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

char *testCases = new char[testCaseCount];

不要忘记删除操作员new分配的内容。

考虑到它不是“一串字符串”。它只是一个字符数组。如果你想获得一个字符串数组,首先应该确定字符串的最大长度。

答案 2 :(得分:1)

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

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

然后你需要为每个字符串分配空间:

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

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

答案 3 :(得分:0)

  

获取异常&#34;分段错误[Core Dumped]&#34;在运行时。

通过在以下位置取消引用未定义的指针,您有未定义的行为:

*testCases = new char[testCaseCount];

  

目标:我想从用户

获取一个字符串数组

中,您使用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;
}

Live demo