Find occurrences of alphabets in a command line argument - c++

I'm new here!
I'm writing this code for class, and I keep getting a segmentation fault(core dumped) error. Why is this happening?
int main(int argc,char *argv[])
{
char *store[100];int freq[100]={0};int flag;int count=0;int t;
for(int i=0,j=0;i<argc;i++)
{
for(int z=0;z<count;z++)
{
if(*argv[i]==*store[z]) flag=1;t=z;break;
}
if(flag==0) {*store[j]=*argv[i];j++; count++;}
else freq[t]+=1;
flag=0;
}
for(int x=0;x<count;x++) cout<<*store[x]<<"\t"<<freq[x]<<endl;
}

You're accessing an unitialised variable, causing undefined behaviour.(int flag)
In the first iteration count will be equal to 0, so the inner loop will not happen, hence no assignment to flag, before using.

It seems that you want compare *argv[1] with *store[z], but what is the value of *store[z] ?
before using any variable, initialize it ! if it is a pointer, make sure that memory is malloced for it.

char *argv[] and char *store[100] are array of pointers to char, i.e. typically an array of null-terminated strings.
The array store is not initialized, so that, it holds 100 pointers pointing to some undefined memory location.
In line:
if(*argv[i]==*store[z]) flag=1;t=z;break;
you are dereferencing the pointer at index z of array store. As this pointer is undefined, the program typically tries to access a protected memory location. Thus, it segfaults.

Related

pointer value change C++ [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 4 years ago.
I'm relatively new too C++ programming. While I was working on a code about arguments passing with an array of character pointers. I encountered a problem where the value of my pointers are changed after certain operations. Below is my code.
#include <iostream>
using namespace std;
void input(char* argv[], int &i)
{
char buff[10][20]; //buffer string array
while (cin.peek() != '\n') {
cin >> buff[i++];
}
for (int j = 0; j < i; j++) {
argv[j] = buff[j];
}
argv[i] = NULL; // putting a NULL at the end
}
int main(int argc, char* argv[])
{
char *arg[10];
int i = 0;
input(arg, i); //input the arguments
for (int j = 0; j < i; j++) {
cout << arg[j] << endl; //output the arguments entered
}
return 0;
}
The sub-function void input(char* argv[], int &i) is supposed to let me input my arguments as many as 9 times or when an enter key is pressed. While i indicates the total number of arguments.
The arguments are then stored as an array of character pointers and then pass it back to the main function's char *arg[10] to hold.
However, I found that after
cout << arg[j] << endl;
The values of arg are lost, and random values are being printed.
You're creating a two-dimensional array of characters buff on the stack, and then you're returning pointers into that array through the argv parameter. But buff lives on the stack and ceases to exist as soon as the input function exits. The memory used by buff will be overwritten by other functions that you call after calling input.
You should allocate buff in main and then pass it into input so it continues to live in the scope of main after input returns.
Another option would be to allocate heap space for buff in input. In this case the main function would be responsible for freeing the memory after it was done with it.
Obviously there are more advanced C++ features you could use to avoid some of this overhead. Though this is a C++ program, it's effectively written as C. But understanding how memory and pointers work is essential to understanding the problems that the newer C++ features solve.
the value of my pointers are changed
The pointers are the only things that weren't damaged. The problem is the memory they point to.
You can prove the first part by printing the value of each of these pointers, or just inspecting them in the debugger. (You can print the address rather than the C-string it points to by casting to void, like cout << static_cast<void*>(arg[j]) << '\n').
So what happened to your C strings? Well, you declared an automatic-scope array variable inside the function input. That array ceases to exist when the function exits, just like any other automatic-scope variable. Accessing the memory where a variable used to live, after the variable ceases to exist, is illegal.
The fact that you returned pointers into this array doesn't make it legal to read through (dereference) them after the array itself goes out of scope, and this is in fact undefined behaviour.
The contents being overwritten is actually the best case, because it meant you noticed the bug: it could legally have crashed or, even worse, appeared to work flawlessly until after you submitted/deployed/sold the program, and crashed every run thereafter.
Think of the stack as being a large (but not unlimited) amount of memory. It is allocated and freed simply be moving the stack pointer down and up (the directions will depend on the hardware).
Here's your code with some annotations.
input(arg, i);
// when you get here the stack pointer will have been moved up, freeing the space
// that was allocated for 'buf' in 'input'
// the space for 'j' could overwrite the space where 'buf' was
for (int j = 0; j < i; j++) {
// the calls to 'cout' and 'end;' could overwrite the space where 'buf was'
cout << arg[j] << endl;
}

What would be output of following program in c++?

#include<iostream>
using namespace std;
void test(int *s){
s++;
*s=3;
}
int main(){
int s=0;
test(&s);
cout<<s;
return 0;
}
The output I am getting 000. I was expecting only 0. But I am getting zeros equal to value assigned to s in test function. I am not able to understand why is it giving this output?
Edited.
Undefined behaviour is undefined. When called like in your main, test writes through an invalid pointer, so anything can happen.
Your program has undefined behavior.
The line
s++;
increments the pointer, not the value of the object the pointer points to.
and then the line
*s=3;
modified the value at of the new location the pointer points to. That is accessing memory that you are not supposed to access.
You passed &s in test function argument so the *s is the actual value but when you incremented s the pointer went to an undefined location and hence the output could be anything. remove the line s++ and you will get 3 as answer.

While loop not functioning on assigning char '\0'

I've tried this program but it doesn't work, IMO it should've stored q at every position on the array, but why is it not happening?
`
int main()
{
char *c=new char[10];
char *p=c+9;
*p='\0'; //This should've assigned the last value to null terminator
int i=0;
p=c;
while(*c)
{
i++;
*c='q';
cout<<*c<<endl;
++c;
}
cout<<i<<endl<<*p<<endl;
return 0;
}
This is really beyond me, please help. Why this loop is not looping for 10 times? It should as the '\0'is at the 10th position.
You ask for 10 chars by new and then you try to go over these chars with while(*c) but since you never initialize this memory block you already have undefined behavior in the first place when you dereference it through *c.
To explain this situation though, there's a good chance you're running this in debug mode in which case there's a good chance that everything returned from new is zeroed out memory (the debugger wants to be nice), which means that your while loop will terminate immediately. Use a for loop instead or explicitly loop until a certain number.

c++ trying to fail constructor

I'm trying to get segment fault, but I can't get it and I wonder why.
#include <iostream>
using namespace std;
class A{
public:
char *field_;
A(char *field):field_(field) {
// I believe(suppose) that it's equal to
// field_ = field;
// so actual initial string wasn't copied, only a pointer to it
}
void show() {
cout<<field_<<"\n";
}
};
int main(){
A *obj;
{
char *line="I should be freed";
obj = new (nothrow) A(line);
}
// After exiting from the previous scope,
// char *line variable should be freed.
// Constructor of class A didn't make byte for byte
//copying, so we cannot have
// access to it for sure
for(int i=0;i<4;i++) // trying to clear stack and erase char *line variable
char something[10000];
obj->show(); // and it works correctly!!!! why?
delete obj;
return 0;
}
Ok, as I understand it works correctly only because that string wasn't freed from memory.
I.e. we are just lucky.
And here we have undefined behaviour. Am I right?
Thank you in advance!!
You won't get a segmentation fault because there are no invalid memory references made by your program. I'd guess you think that ""I should be freed" is created on stack and then destroyed or freed somehow, and that is a wrong assumption because that is a constant string literal and it is placed into program data segment and is "alive" for the life of your program.
And even if it was allocated dynamically and freed automatically upon leaving the scope, you still cannot expect your program to receive SIGSEGV in that case. Because undefined behavior does not always result in segmentation faults.
Also, try to never write char *data = "blah-blah";. String literals are assumed to always be constant and trying to modify them is undefined behavior. Though people still hack around this sometimes.
char *line = "I should be freed";
You still see the content because the string literals has static storage duration. Here the string literal I should be freed resides in read only location and is freed once the program execution completes.
The program has no undefined behavior.

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.