Why am I getting a Segmentation fault: 11 in my C++ program? - c++

I am currently experiencing trouble with an Segmentation fault : 11 in my C++ Program which uses object-oriented concepts:
//
// main.cpp
// pointersInOOP
//
// Created by Jayant Raul Rao on 15/05/15.
// Copyright (c) 2015 Jayant Raul Rao. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
class Student
{
public:
char * name;
int semesterHours;
float gpa;
};
int main(int argc, const char * argv[]) {
cout<<"Beta Version of 1.0 Student constructor. \n";
cout<<"\n";
cout<<"\n";
//Declaring a student object and a pointer
Student s;
Student *pOnS = &s;
//take userInput
printf("Please name the student... : ");
cin>>pOnS->name;
printf("Okay, you called your Student %s. Please now input the gpa of the Student: ", pOnS->name);
cin>>pOnS->name;
printf("The gpa of %s is %f", pOnS->name, pOnS->gpa);
return 0;
}
And when I execute this code I actually give my input and that always ends in a Segmentation fault. This error I get if I execute in the Terminal. If I execute directly in Xcode I get directed to a file called istream where there is written at a line: Bad access 0x1. Therefore I am unable to execute my program. I have already found out what Segmentation fault means.
Something like literally Stack Overflow. But I am unable to really understand any bugfix.
I thank you in advance,
Jayant Raul Rao

This code is un tested, but the main point is that it would be easier if you use a String type for the student name. So if you change char *name to std::string name your code will work.
If you want to stick to using char then you have to do something like this.
#include <string>
...
//take userInput
printf("Please name the student... : ");
std::string name;
cin>>name;
pOnS->name = new char(name.size() + 1);
strncpy(pOnS->name, name.c_str(), name.size());
pOnS->name[name.size() + 1] = '\0';
P.S fix this:
printf("Okay, you called your Student %s. Please now input the gpa of the Student: ", pOnS->name.c_str()); <-- if using String type
cin>>pOnS->gpa; //<----

class Student
{
public:
char * name; //you are not allocating memory for this.
int semesterHours;
float gpa;
};
You could use a character array like char name[15] or std::string
Also you are not initializing gpa before printing it.

A segmentation fault indicates some sort of invalid memory access. In this case, you're declaring a pointer (char * name), but never initializing it. So it points to some arbitrary value, which may or may not be a valid memory address. Then you try to write through it: cin>>pOnS->name;. This is undefined behaviour, which is likely to result in one of the following:
If the pointer's value is not a valid writable memory address, then you'll get a crash right away; the error that you'll get depends on the OS, but the most common ones are "segmentation fault", "general protection fault", or "bus error".
If the pointer's value is a valid writable memory address, then you'll overwrite whatever happens to be there. This may seem to work correctly, only for it to crash unpredictably when you try to run your program on a different computer, or at a different time. Or it may corrupt something that your program will try to use later, resulting in a crash in unrelated code.
To avoid this problem, ensure that you always write to valid memory locations. The easiest way to do that in this case is to use std::string rather than a raw character array.
Also, I think that your second write to pOnS->name should actually be to pOnS->gpa.

pons = new student;
Use the above statement after declaring pons as an object reference in the function. Rest looks fine and it worked for me hope it does for you too.

Related

Deleting an array element declared in struct c++

I want to delete the array elements declared under student struct. I have only included parts of the code to reduce confusion.Please find the code below for the two relevant cases:
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
struct student
{
char name[20];
int id;
};
struct teacher
{
char name[20];
int id;
};
int main()
{
case 1:
cout<<"\t\t\t*********enter record**********"<<endl;
student st[2];
for(int count=0; count<2;count++)
{
cout<<"\t\t\t\tenter student "<<count<<" name"<<endl;
cin>>st[count].name;
cout<<"\t\t\t\tenter student "<<count<<" id"<<endl;
cin>>st[count].id;
}
break;
case 5:
cout<<"\t\t\t*********delete record********"<<endl;
for(int count=0;count<10;count++)
{
delete st[count].name;
}
break;
}
As seen in case 5 I am trying to delete the elements within the array using delete st[count].name;
I want to delete the elements of name and id in the delete case. However using delete st[count].name gives me a [Warning] Deleting array . And when I run the program it gives me a Program Recieved a signal SIGTRAP, trace/breakpoint trap. I am a beginner in c++ please help how I can delete the elements stored in these array. Thanks
There are 2 main problems in your code.
cin>>st[count].name
You're filling the array with user input, but the array can only hold 20 elements (and the last one must be a null terminator), if user inputs text with more then 19 elements, your program will result in undefined behavior.
Later, you're using
delete st[count].name
You're using delete on an array that is allocated on the stack, which is undefined behavior again, you would only need to use delete if you alocate an object using operator new, also you should use delete[] instead of delete for arrays.
The easiest fix to your program is changing char name[20] to std::string, std::string will resize itself to adapt to the text that it's holding dynamicly, while also taking care of clearning memory after itself, so you don't have to worry about that, later on it also has many useful methods that you may find useful, you can read more about std::string.
https://en.cppreference.com/w/cpp/string/basic_string

file handling I/O c++ error

this is the code which i am trying to run.The compiler shows some warning that the variable 'p' may be possible to be used uninitialized.
And ..on running it has a problem ..i will show..below.
please correct me and explain .
Thank you.
execution of code
*
code
that error is that..the first two elements of the character array being output are somewhat messed up!!!*
#include<bits/stdc++.h>
using namespace std;
class file{
public:int a;
char* name;
public:
file(int x,char* b):a(x){name=b;}
void printfile(){cout<<a<<" "<<name<<endl;}
};
int main(){
char *p;
int x=10;
cout<<"enter a name"<<endl;
cin>>p;
file k(x,p);
ofstream f("file",ios::out|ios::binary);
f.write((char*)&k,sizeof(class file));
f.close();
ifstream of("file",ios::in|ios::binary);
file o(0,'\0');
of.read((char*)&o,sizeof(class file));
o.printfile();
of.close();
return 1;
}
You have p as some pointer. Who is going to allocate the memory that pointer points to?
In C it is almost always the responsibility of the caller to allocate any buffers before the call.
If you don't want to, then use a std::string instead.
First of all I would advise you to read some basic manual about the c++ pointers and memory handling so you will better understand the source of the problem.
There are two major problems in your code.
The first is that you are creating a pointer which is not connected to any allocated memory. In simple words you are asking to access a memory address without asking the system to reserve it for you.
Additionally, in that memory location there can already be stored any bit configuration. The initialization of a variable is the task of giving a chunk of memory some data which have a meaningful interpretation. I'm not even sure what the in-stream operator of char* is supposed to do in this particular case. He is probably appending your characters after the last one which is not a 0 or an end of line.

String reversal in C++ getting 'Segmentation fault (core dumped) error

This below gives me 'Segmentation fault (core dumped)' error after printing the reversed string. Can anyone explain why ?
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
void print (char *str) {
if (*str) {
print (str+1);
cout << *str;
}
}
int main() {
char *str;
cin >> str;
print(str);
cout << endl;
return 0;
}
Uninitialized non-static local variables have an indeterminate value, and will in reality be seemingly random. Using them without initialization leads to undefined behavior, which is one of the most common causes of crashes.
The problem is that you have a pointer, but it doesn't point anywhere so when you use it to read input, the input stream cin will write to a random location in memory.
The solution is to not use character pointers for string, but the std::string class.
If you have to use pointers, then you have two solutions: Either declare the string as an array, or allocate memory using the new operator. However be cautioned that if you input more than you have allocated you will write out of bounds and once again have undefined behavior.
You have not allocated any memory to char *str. Try using char str[20] (20 is just an example, it could be anything as per your demand and your machine's capability) and everything will be fine. You are assuming that compiler will allocate memory for you but that's not the case. You are trying to access an unallocated memory or you can dynamically allocate them using malloc or new.
More than that you can use std::string to do get help from stl.
Either declare the str like char str[fixed_size] or use std::string. One of the simplest methods to do that might be this:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string str;
cin >> str;
reverse(str.begin(),str.end());
cout <<str<< endl;
return 0;
}

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:
Allocate memory for ptr[i] (even when i is zero).
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:
std::istringstream
std::vector
std::copy
std::istream_iterator
std::back_inserter
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.

C++ Assignment, strcpy and strlen with character arrays n pointers

I am working on this assignment and have encountered a problem. At one point, I have to ask the user for two input commands to be used later and I want them put in a char array. I then want to put the input they have into char* but I end up with a Segmentation fault
Here is a small part of my code that shows where I'm having problems:
#include <iostream>
#include <cstring>
using namespace std;
int main(){
char firstAns[80];
char * command1[5];
int ansLen;
//Ask for command
cout << "Please enter your first command(incl. args) or quit: ";
cin >> firstAns;
ansLen = strlen(firstAns);
for(int i=0; i < ansLen; i++){
strcpy(command1[i], firstAns);
}
The program that I ran this from compiles just fine but I have narrowed the segmentation fault to this part of the program and could use some help as a novice programmer :)
You have an array of char* called command. But you haven't allocated any memory for the pointers in the array, or even set them to null. SO they're random values, pointing to random memory locations. Strcpy is then overwriting those random locations, causing a seg fault. You need to allocate memory for those pointers by command[i]=new char[80] on all 5 rows first.
char * command1[5];
This is an array of char*s. However, it is uninitialized - the values can be any value, and as such they point to random, meaningless places in memory.
You then later use the uninitialized command1[i] in strcpy(command1[i], firstAns);. Essentially, what you have done is taken a random place in memory and tried to copy firstAns to it. No wonder your program crashes!
Before using a pointer, you have to initialize it to some value. If you need storage in memory, use malloc() to return storage of the correct size (sizeof(datatype)*length +1 if it is a string) and remember to free() the pointer returned from it when you're done with it.
Read more: http://www.cplusplus.com/reference/cstdlib/malloc/
(Gabe Sechan's solution is also valid. new and malloc are the C++ and C ways of allocating memory)
Additional Problem is here:
ansLen = strlen(firstAns);
for(int i=0; i < ansLen; i++){
strcpy(command1[i], firstAns);
}
ansLen is the length of firstAns, it may be possible that it is longer than 5. In this case,
if you try to access command1[i], you are going to access memory that out of bounds, results in segfault.
Meanwhile, you are using unitialized command1 as pointed out by Patashu and Gabe.