代码中的分段错误

时间:2013-08-14 10:34:06

标签: c++ linux segmentation-fault

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

Segmentation fault (core dumped)

我用gdb进行调试。但是在我第二次循环访问后,它显示了
Program received signal SIGSEGV, Segmentation fault. 0x0000003b64a81321 in __strlen_sse2 () from /lib64/libc.so.6

它的解决方案是使用
ptr[i]strcpy(ptr[i],cp);之前为每个ptr[i]=new char[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;
}

4 个答案:

答案 0 :(得分:4)

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

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

  1. ptr[i]分配内存(即使i为零)。
  2. 将指针cp改为ptr[i]

  3. 在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';
    }
    

    这个输出是:

    hello
    world
    how
    are
    you
    today
    

    以下是使用的函数/类的引用列表:

答案 1 :(得分:2)

当您尝试访问不允许您的程序的内存部分时,会发生分段错误。当你这样做

char * p [10];

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

实际上由于行而发生分段错误:

strcpy(ptr[i],cp);

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