2013-08-14 5 views
0

Здесь я в основном пытаюсь ввести строку, разбить ее на отдельные слова и назначить каждое слово указателю char ptr[i]. При выполнении следующего кода, если я ввожу строку из более чем одного слова, он показывает

Segmentation fault (core dumped).

Я использовал gdb для отладки. Но после того, как я захожу в то время как время 2-й цикл, он показал

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; 
} 
+0

Здесь есть хороший вопрос о разделении строки. Ответы работают лучше, чем 'strtok'. – chris

+0

@chris: Где? – user2672165

+0

Если вы указали ссылку в «здесь», отредактируйте комментарий и измените, потому что это простое слово без ссылки. – Smith

ответ

4

При объявлении локальной переменной, это содержание является неопределенным . Поэтому, когда вы объявляете массив указателей, указатели в массиве будут указывать на кажущиеся случайными местоположения. Использование неинициализированного указателя не определено поведение. Неопределенное поведение может привести к сбою, или может, похоже, работает, но вы не можете сказать заранее, что произойдет.

Есть два пути решения вашей проблемы:

  1. Выделяет память для ptr[i] (даже если i равен нуль).
  2. Вместо этого назначьте указатель 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'; 
} 

Выход из этого:

 
hello 
world 
how 
are 
you 
today 

Вот список ссылок для используемых функций/классов:

2

Сегментация Fault возникает при попытке получить доступ к той части памяти, что ваша программа не является не разрешается. Когда вы делаете

char * p [10];

определяет массив из 10 указателей. Содержимое массива неизвестно. Следовательно, это может быть местоположение памяти вне вашей программы.Возможно, 0-й индекс имеет некоторое значение, которое является частью адресного пространства вашей программы, и, следовательно, оно не жаловалось. Второй индекс имел то, что не является частью вашего адресного пространства.

Таким образом, поведение не определено. Это полностью зависит от содержимого массива.

0

Иногда мы можем получить ошибку сегментации при использовании ptr [0], но это может быть не всегда. И всегда лучше выделять память указателю перед назначением любых значений объекту, на который он указывает.

0

Собственно ошибка сегментации происходит из-за линии:

strcpy(ptr[i],cp); 

Если выделить память для ptr[i] либо new или malloc, а затем скопировать его не отстойник.

Смежные вопросы