Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 代码中的分段错误_C++_Linux_Segmentation Fault - Fatal编程技术网

C++ 代码中的分段错误

C++ 代码中的分段错误,c++,linux,segmentation-fault,C++,Linux,Segmentation Fault,在这里,我基本上是尝试输入一个字符串,将其分解为单个单词,并将每个单词分配给一个char指针ptr[I]。在执行以下代码时,如果我输入多个单词的字符串,它将显示分段错误(内核转储)我使用gdb进行调试。但在我第二次访问while loop后,它显示程序接收到信号SIGSEGV,分段错误。 0x0000003b64a81321,位于/lib64/libc.so.6中的 它的解决方案是在strcpy(ptr[i],cp)之前为每个ptr[i]分配内存使用ptr[i]=新字符[sizeof(cp)]

在这里,我基本上是尝试输入一个字符串,将其分解为单个单词,并将每个单词分配给一个char指针
ptr[I]
。在执行以下代码时,如果我输入多个单词的字符串,它将显示

分段错误(内核转储)


我使用gdb进行调试。但在我第二次访问while loop后,它显示

程序接收到信号SIGSEGV,分段错误。
0x0000003b64a81321,位于/lib64/libc.so.6中的


它的解决方案是在strcpy(ptr[i],cp)之前为每个
ptr[i]
分配内存使用

ptr[i]=新字符[sizeof(cp)]

但是,为什么ptr[0]不需要内存分配?如果我不为ptr[0]分配内存,是否有可能覆盖其他内容?我问这个问题是出于好奇,我知道分配内存总是更好。
下面是代码:

#include<iostream>
#include<cstring>
#include<string>
using namespace std;

int main()
{   
    int i,j;
    string s1;
    getline(cin,s1);
    char s[100],*ptr[10];
    strcpy(s,s1.c_str());
    char *cp;

    cout<<"string is:  "<<s1<<endl;
    cp=strtok(s," ");
    i=0;
    while(cp!=NULL)
    { cout<<cp<<endl;
      strcpy(ptr[i],cp);
      cp=strtok(NULL," ");
      i++;
    }

    for(j=0;j<i;j++)
    { cout<<ptr[j]<<endl;
    }
    return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{   
int i,j;
字符串s1;
getline(cin,s1);
chars[100],*ptr[10];
strcpy(s,s1.c_str());
char*cp;

cout当您声明一个局部变量时,它的内容是未定义的。因此,当您声明一个指针数组时,数组中的指针将指向看似随机的位置。使用未初始化的指针是未定义的行为。未定义的行为可能会导致崩溃,或者看似有效,但您无法事先说明会发生什么嗯

您的问题有两种解决方案:

  • ptr[i]
    分配内存(即使
    i
    为零)
  • 将指针
    cp
    指定给
    ptr[i]

  • 在空间中分割字符串可以比C++所做的更简单,例如,参见下面的简单程序:

    #include <iostream>
    #include <vector>
    #include <sstream>
    #include <algorithm>
    
    int main()
    {
        // Put a string into a string stream
        std::istringstream is("hello world how are you today");
    
        // Vector where to store the "words"
        std::vector<std::string> words;
    
        // Now split the string on space    
        std::copy(std::istream_iterator<std::string>(is),
                  std::istream_iterator<std::string>(),
                  std::back_inserter(words));
    
        // And finally print the words
        for (const auto& word : words)
            std::cout << word << '\n';
    }
    
    #包括
    #包括
    #包括
    #包括
    

  • 当您声明局部变量时,它的内容是未定义的。因此,当您声明指针数组时,数组中的指针将指向看似随机的位置。使用未初始化的指针是未定义的行为。未定义的行为可能会导致崩溃,或看似有效,但您无法事先说明会发生什么钢笔

    您的问题有两种解决方案:

  • ptr[i]
    分配内存(即使
    i
    为零)
  • 将指针
    cp
    指定给
    ptr[i]

  • 在空间中分割字符串可以比C++所做的更简单,例如,参见下面的简单程序:

    #include <iostream>
    #include <vector>
    #include <sstream>
    #include <algorithm>
    
    int main()
    {
        // Put a string into a string stream
        std::istringstream is("hello world how are you today");
    
        // Vector where to store the "words"
        std::vector<std::string> words;
    
        // Now split the string on space    
        std::copy(std::istream_iterator<std::string>(is),
                  std::istream_iterator<std::string>(),
                  std::back_inserter(words));
    
        // And finally print the words
        for (const auto& word : words)
            std::cout << word << '\n';
    }
    
    #包括
    #包括
    #包括
    #包括
    

  • 当您试图访问程序不允许访问的内存部分时,会出现分段错误。如果您这样做

    char*p[10]

    它定义了一个由10个指针组成的数组。数组的内容未知。因此它可能是程序外部的内存位置。可能第0个索引的某个值是程序地址空间的一部分,因此它没有抱怨。第2个索引的某个值不是程序地址空间的一部分


    因此,行为是未定义的。它完全取决于数组的内容。当您试图访问程序不允许访问的内存部分时,会出现分段错误。当您这样做时

    char*p[10]

    它定义了一个由10个指针组成的数组。数组的内容未知。因此它可能是程序外部的内存位置。可能第0个索引的某个值是程序地址空间的一部分,因此它没有抱怨。第2个索引的某个值不是程序地址空间的一部分


    因此,行为是未定义的。它完全取决于数组的内容

    有时我们在使用ptr[0]时可能不会出现分段错误,但情况可能并非总是如此。在将任何值分配给指针所指向的对象之前,最好先将内存分配给指针。

    有时,使用ptr[0]时,可能不会出现分段错误,但情况可能并非总是如此。在将任何值分配给指针所指向的对象之前,最好先为指针分配内存。

    实际上,分割错误是由以下行引起的:

    strcpy(ptr[i],cp);
    

    如果您使用
    new
    malloc
    将一些内存分配给
    ptr[i]
    ,然后进行复制,则不应将其存储在内存池中。

    实际分段故障是由以下行引起的:

    strcpy(ptr[i],cp);
    

    如果您使用
    new
    malloc
    ptr[i]
    分配一些内存,然后将其复制,则不应将其存储。

    这里有一个关于拆分字符串的好问题。答案比
    strtok
    更有效。如果您在“此处”中提供链接,请编辑注释并修改,因为它只是一个简单的单词,没有链接。搜索框是一个选项(里面有一个非常好的单词序列),但是@chris,但是我们必须将子字符串分配给char ptr,因此,我们必须在其中再次编写大量代码。那么,为什么你认为这比strtok更好呢?(执行时间少了还是什么?)有一点是可以重新进入的。从字符串中获取
    (const)char*
    非常容易。这里有一个关于拆分字符串的好问题。答案比
    strtok
    更有效。如果您在“此处”中提供链接,请编辑注释并修改,因为它只是一个简单的单词,没有链接。搜索框是一个选项(里面有一个非常好的单词序列),但是@chris,但是我们必须将子字符串分配给char ptr,因此,我们必须在其中再次编写大量代码。那么,为什么你认为这比strtok更好呢?(执行时间少了还是什么?)它是可重入的。很容易从字符串中获取
    (const)char*