分段错误

时间:2016-02-11 14:10:58

标签: c++ c-strings

我正在尝试在Linux中实现自己的shell。我从用户那里获取输入并解析它。但是当我在数组中复制我的标记时,它会出现分段错误。我无法解决这个问题。

这是我实施的代码

#include <iostream>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>

using namespace std;

int main ()
{
    char * input;
    string insert;
    cout<<"My Shell $";

    getline(cin,insert);
    input= new char [insert.size()+1];
    strcpy(input, insert.c_str());


    char * token;
    char * parsed[100];
    int count;

    token=strtok(input, " ");
    while (token!=NULL)
    {
        strcpy(parsed[count],&(token[count]));
        count++;
        token=strtok(NULL, " ");
    }


}

6 个答案:

答案 0 :(得分:3)

#include <string.h>

没有

如果您想要C函数,请使用<cstring>,将它们放在std::命名空间中。

但你不想想要 C函数,你想要C ++ <string>。相信我,你做到了。

using namespace std;

为了这个例子,我会让那个过去。在任何生产代码中摆脱这种特殊习惯。

    getline(cin,insert);

好。你已经准备好做C ++了。

    input= new char [insert.size()+1];
    strcpy(input, insert.c_str());

坏。你只是将双手绑在背后。

    char * parsed[100];

一个包含100个char指针的数组。只是指针,未初始化,指向无处。

    int count;

未初始化。

    token=strtok(input, " ");

℃。 颤动 ....

        strcpy(parsed[count],&(token[count]));

未定义的行为。 count未初始化,即使 恰好在0到99之间,parsed[count]仍未指向有效内存,因此将内容复制到其中做坏事。

此外,您的令牌位于token,而不是token[count] ...

        count++;

在未初始化时添加1是UB,仍然未初始化。 ; - )

}

你忘了delete [] input

让我建议一个不同的,更多的C ++ - ish方法,它仍然会给你指向每个标记的指针数组(如果你坚持的话):

getline( cin, input );

// turn spaces to null bytes
std::replace( input.begin(), input.end(), ' ', '\0' );

// need an additional one for the finds below to work
input.append( '\0' );

// vector takes away all of that manual memory management
std::vector< char * > parsed;

size_t i = 0;

// skip leading (ex-) spaces
while ( ( i = input.find_first_not_of( '\0', i ) ) != std::string::npos )
{
    // push the pointer to the token on the vector
    parsed.push_back( input.data() + i );

    // skip to end of token
    i = input.find( '\0', i );
}

此时,parsedvectorchar * input的代币input(至少,只要parsed.size()本身仍在范围)。您可以使用parsed.data()检查其大小,并使用vector将其作为“裸”数组访问,但我相信您会发现input更方便。

如果您不想保留std::vector< char * > parsed; ,请替换

std::vector< std::string > parsed;

parsed.push_back( input.data() + i );

parsed.push_back( std::string( input.data() + i ) );

vector

您的if (list != null) { while (continue_) { i++; Thread.Sleep(5000); Thread thrd1 = new System.Threading.Thread(() => Test()); thrd1.Start(); } } 中有令牌的副本

这仍然是非常粗略的处理,请注意,因为引号内的偶数空格将被检测为“令牌结束”,但至少它是C ++,没有C字符串处理。

答案 1 :(得分:1)

变量int count未定义,意味着它可以是随机值,将其更改为int count = 0;

答案 2 :(得分:1)

您没有初始化变量count,并且其值未定义(可能非常大,因此程序将无法从内存中读取)。您应该使用int count = 0;

数组parsed中的元素未初始化,也未指向已分配的内存。您对strcpy的调用行为也未定义。在致电parsed[count] = new char[strlen(token) + 1];之前添加strcpy。一切都完成后,不要忘记使用delete

最后,我认为您没有正确使用strtok。你为什么用&(token[count])?也许你应该用token替换它。

答案 3 :(得分:0)

只需将您的计数变量初始化为0

答案 4 :(得分:0)

Please try to use this code. I tried in VS2010 and it is working fine now.

#include <iostream>
#include <string.h>
#include <string>
using namespace std;

int main (void)
{
    char* input = NULL;
    string insert;
    cout<<"My Shell $";

   /* getline(cin, insert);*/
    std::getline(cin, insert);
    input= new char[insert.size() + 1];
    strcpy(input, insert.c_str());

    char* token = NULL;
    char* parsed[100] = {0};

    int count = 0;

    token = strtok(input, " ");

    while ( token != NULL)
    {
        parsed[count] = token;
        count++;
        token = strtok(NULL, " ");
    }

    for ( int index = 0; index<count; index++ )
    {
        cout << parsed[index] << std::endl;
    }

    system("pause");
    return 0;
}

答案 5 :(得分:-1)

请尝试以下代码#

#include <iostream>
#include <unistd.h>
#include <string.h>

using namespace std;

int main (void)
{
    char* input = NULL;
    string insert;
    cout<<"My Shell $";

    getline(cin, insert);
    input= new char[insert.size() + 1];
    strcpy(input, insert.c_str());

    char* token = NULL;
    char* parsed[100];

    for (int index = 0; index < 100; index++)
    {
        parsed[index] = NULL;
    }

    int count = 0;

    token = strtok(input, " ");

    while ( token != NULL)
    {
        strcpy(parsed[count], &(token[count]));
        count++;
        token = strtok(NULL, " ");
    }

return 0;
}