首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态初始化2d字符数组时出现分段错误[核心转储]

问动态初始化2d字符数组时出现分段错误[核心转储]
EN

Stack Overflow用户
提问于 2014-06-06 02:35:02
回答 3查看 480关注 0票数 0

我想从user那里得到一个字符串数组。我在运行时得到了异常“分段错误核心转储”。

代码语言:javascript
复制
#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];
    }
}
EN

回答 3

Stack Overflow用户

发布于 2014-06-06 03:23:22

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

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

也就是说,下面是代码。我让你来决定哪一个更容易出错和bug(我刚刚在网上写了这两个,所以肯定会有bug)。

Hard Way

代码语言:javascript
复制
#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;
}

简单的方法

代码语言:javascript
复制
#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;
}
票数 3
EN

Stack Overflow用户

发布于 2014-06-06 02:40:10

你至少要写成

代码语言:javascript
复制
char **testCases = new char *;
*testCases = new char[testCaseCount];

尽管还不清楚为什么不想简单地写成

代码语言:javascript
复制
char *testCases = new char[testCaseCount];

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

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

票数 2
EN

Stack Overflow用户

发布于 2014-06-06 02:49:29

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

代码语言:javascript
复制
char** testCases = new char*[testCaseCount];

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

代码语言:javascript
复制
testCaseCount[i] = new char[maxStringLength];
cin >> testCaseCount[i];

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24067710

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档