在这里,我基本上尝试输入一个字符串,将其分成单个单词并将每个单词分配给一个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;
}
答案 0 :(得分:4)
声明局部变量时,其内容为 undefined 。因此,当您声明一个指针数组时,数组中的指针将指向看似随机的位置。使用未初始化的指针是未定义的行为。未定义的行为可能导致崩溃,或可能看似有效,但您无法预先说明会发生什么。
您的问题有两种解决方案:
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';
}
这个输出是:
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]
或new
为malloc
分配一些内存,然后将其复制,则不应该使用。