简体   繁体   中英

Segmentation fault in the code

Here, I am basically trying to input a string, break it into individual words and assign each word to a char pointer ptr[i] .On executing the following code, if I input string of more than one word, it shows

Segmentation fault (core dumped) .

I used gdb for debugging. But after I visit while loop 2nd time, it showed

Program received signal SIGSEGV, Segmentation fault. 0x0000003b64a81321 in __strlen_sse2 () from /lib64/libc.so.6

The solution for it is to allocate memory to each ptr[i] before strcpy(ptr[i],cp); using

ptr[i]=new char[sizeof(cp)]; .

But, how is it that no memory allocation needed for ptr[0]? If I don't allocate memory to ptr[0], are there any chances of something else being overwritten? I am asking it out of curiosity, I know its always better to allocate memory.
Here is the code:

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

When you declare a local variable, it's contents is undefined . So when you declare an array of pointers, the pointers in the array will be pointing to seemingly random locations. Using an uninitialized pointer is undefined behavior . Undefined behavior may lead to a crash, or it may seemingly work, but you can't say beforehand what will happen.

There are two solutions to your problem:

  1. Allocate memory for ptr[i] (even when i is zero).
  2. Assign the pointer cp to ptr[i] instead.

Splitting a string on space can be done much more simpler in C++ than what you have though, see for example the following simple program:

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

The output from this is:

hello
world
how
are
you
today

Here's a list of references for the used functions/classes:

Segmentation Fault occurs when you try to access that part of memory that your program is no allowed to. When you do

char *p[10];

it defines an array of 10 pointers. The content of array is unknown. Hence it could be memory location outside your program's. Possibly the 0th index has some value that is part your program's address space and hence it didn't complain. 2nd index had something that is not part your address space.

So, the behaviour is undefined. It totally depends on the content of array

Sometimes we may get no segmentation fault while using ptr[0], but this may not be the case always. And it is always better to allocate memory to the pointer before assigning any values to the object to which it is pointing.

Actually segmentation fault occurs due to the line :

strcpy(ptr[i],cp);

If you allocate some memory to ptr[i] with either new or malloc and then copy it should not sump.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM