News:

Help! We're trapped in the computer, and the computer is trapped in 2008! Someone call the time police!

Main Menu

Segmentation Fault

Started by AntiVirus, October 28, 2006, 02:06:54 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AntiVirus

I am not sure why I am getting a segmentation fault.  It shouldn't be going over the memory I allocated for it, but it seems to be.

Any ideas?


void dsply_chg()

{
  ifstream in;
  char story[150];
  char * target;

  in.open("index.dat");

  cout<<endl;
  cout<<"Changes have been made!";
  cout<<endl;
  while(in >> story)
  {
     target = strstr(story, "*adj*");
     strncpy(target, "BLAH", 3);
     cout<<story<<" ";
  }
  in.close();
}


It displays "Changes have been made" then says "Segmentation fault".  Not sure where it is, and since I am experimenting with functions, I don't know if I am using them wrong or not.  So, any ideas?
The once grove of splendor,
Aforetime crowned by lilac and lily,
Lay now forevermore slender;
And all winds that liven
Silhouette a lone existence;
A leafless oak grasping at eternity.


"They say that I must learn to kill before I can feel safe, but I rather kill myself then turn into their slave."
- The Rasmus

iago

This will help you a lot, whenever it happens. 

Do this:
- Compile the program as normal, but add -g (if you don't already)
- Run "gdb <programname>"
- You should get a prompt, (gdb) .. type "run" and press enter
- When it crashes, type "backtrace" and hit enter

That should make your life easier.  Type "quit" to quit that. 



But to actually answer your question, you should never use functions like strstr() without checking the return value.  If the string wasn't found, strstr() returns NULL (0).  If it returns 0, you should fail with an error message or something.

AntiVirus

#2
Well it should be able to find *adj* in there, but as a safety thing, I see where you are comming from.

Anyway, I did that and I got this:

QuoteProgram received signal SIGSEGV, Segmentation fault.
0x00406649 in strncpy () from /lib/tls/libc.so.6
(gdb) backtrace
#0  0x00406649 in strncpy () from /lib/tls/libc.so.6
#1  0x08048cc9 in ?? ()
#2  0x08048f59 in ?? ()
#3  0x003b1de3 in __libc_start_main () from /lib/tls/libc.so.6
#4  0x08048965 in ?? ()

What does that mean?  Something is wrong with my strncpy?  Is it returning NULL?
The once grove of splendor,
Aforetime crowned by lilac and lily,
Lay now forevermore slender;
And all winds that liven
Silhouette a lone existence;
A leafless oak grasping at eternity.


"They say that I must learn to kill before I can feel safe, but I rather kill myself then turn into their slave."
- The Rasmus

Sidoh

No, you're passing it NULL in the parameter target, I think.  You need to add error checking to make sure that strstr() returns what you're expecting it to.

iago

You said that "print buf" returns '0' -- which means that buf is 0, or null.  That means that strstr() is returning NULL. 


And that backtrace doesn't have function names or line numbers because you didn't compile your program with "-g". 

AntiVirus

I did too!!  I don't know if I put it in the right spot, but I put it in my cmd line!  Either way, I got it to where it prints out "BLAH" at every noun ( I changed it to *nouns*), so now I need to find a way to delete the string *nouns* and remove the newline character so it is formatted correctly. 

This project is like a madlib, and so I have to use a random number generator to generate a random word from a file depending on it being a noun, adj, verb, etc.  So that's what I am doing.

I wonder if there is a strdel() function!!
The once grove of splendor,
Aforetime crowned by lilac and lily,
Lay now forevermore slender;
And all winds that liven
Silhouette a lone existence;
A leafless oak grasping at eternity.


"They say that I must learn to kill before I can feel safe, but I rather kill myself then turn into their slave."
- The Rasmus

iago

There's no strdel() function, string manipulation in C is a bare minimum (str* functions are C, not C++). 

If not every line has a *adj*, then your strstr() call will return NULL.  Have you tried checking the return value of strstr() before using it, yet?

And the -g can go anywhere on the commandline, but if you included it then there shouldn't be the ???'s, so something is going wrong..

AntiVirus

#7
QuoteIf string2 is not found in string1 the function returns NULL.
Hrmm... so I need to make it to where it keeps going until it finds one, when it returns NULL?

So like:

if(target == NULL)
{
     target = strstr(story, "*adj*");
     strncpy(target, "BLAH", 3);
     cout<<story<<" ";
}

Would that make it go to the next line and search for it there?  Because right now I have it printing out "Blah" right after it finds the string, but it doesn't replace the two like the strncpy is suppose to do!  So would that fix that problem?
The once grove of splendor,
Aforetime crowned by lilac and lily,
Lay now forevermore slender;
And all winds that liven
Silhouette a lone existence;
A leafless oak grasping at eternity.


"They say that I must learn to kill before I can feel safe, but I rather kill myself then turn into their slave."
- The Rasmus

Sidoh

Target will only be null if it doesn't find the string in "story."  Do you really want to write "BLAH" to >null< if nothing is found?!

AntiVirus

Eh, that's right.

So, would it be if(target == !NULL)?

But if it is NULL, what do I do? 
The once grove of splendor,
Aforetime crowned by lilac and lily,
Lay now forevermore slender;
And all winds that liven
Silhouette a lone existence;
A leafless oak grasping at eternity.


"They say that I must learn to kill before I can feel safe, but I rather kill myself then turn into their slave."
- The Rasmus

Sidoh

Quote from: AntiVirus on October 29, 2006, 02:35:16 AM
Eh, that's right.

So, would it be if(target == !NULL)?

But if it is NULL, what do I do? 

You'd want to do if(target != NULL) or if(! (target == NULL) ).  target == !NULL might do some funny things, since NULL isn't a boolean object.

Well, think about what it means when strstr returns NULL.  Check out the documentation.

Here's a good piece of advice: before you start writing a program, step back and come up with an abstract solution to the problem. Then worry about the semantics of the program.  Don't just jump right in and start programming.  Also, make sure you know of a way to tackle the problem entirely.  Don't leave too many details out, or things could get sloppy!  Before writing this program, you should take a look at some documentation for the C 'string' manipulation functions.  Check to see how they behave when you give it strange parameters and make sure you handle all possible results.

AntiVirus

Yeah, I have NO idea why I wrote target == !NULL. I meant target != NULL.  Anyway, I did do some reasearch before I started this project and got a pretty good idea of how to tackle it, but it isn't working like the demonstrations on the site.  So, that's where the problem came about.

Hrmm.. as for if it returns NULL on that line.. Hrmm.. I will have to think about that.
The once grove of splendor,
Aforetime crowned by lilac and lily,
Lay now forevermore slender;
And all winds that liven
Silhouette a lone existence;
A leafless oak grasping at eternity.


"They say that I must learn to kill before I can feel safe, but I rather kill myself then turn into their slave."
- The Rasmus

Sidoh

Quote from: AntiVirus on October 29, 2006, 03:26:39 AM
Yeah, I have NO idea why I wrote target == !NULL. I meant target != NULL.  Anyway, I did do some reasearch before I started this project and got a pretty good idea of how to tackle it, but it isn't working like the demonstrations on the site.  So, that's where the problem came about.

Hrmm.. as for if it returns NULL on that line.. Hrmm.. I will have to think about that.

http://www.thinkage.ca/english/gcos/expl/c/lib/strstr.html

Quote#include <string.h>
ptr = strstr( s, subs );
Where:
const char *s;
points to the string to be scanned.
const char *subs;
points to the (sub)string to scan for.
char *ptr;
points to the first occurrence of the substring in the given string. If the substring is not found, this will be a null pointer.
Description:

"strstr" returns a pointer to the first occurrence of a substring within another string.

If it doesn't find the substring within the string, it returns NULL.

iago

Yeah, what Sidoh's saying.  You're on the right track. 

while()
{
  var = strstr(whatever);
  if(var != NULL)
  {
    /* do stuff */
  }
}

AntiVirus

  while(in >> story)
  {
    target = strstr(story, "*nouns*");
    if(target != NULL)
    {
      strncpy(target, "BLAH", 5);
      puts (story);
    }
    cout<<story<<" ";
  }

That works, but it is printing out "BLAH" right before the *noun* and then it replaces *noun* with blah.  And I tried to use the ignore() function to ignore the \n character or whatever character it is that is making it go to a new line after it inserts the BLAH right before the *noun*.  I will have to look at that more when I get back, but if you guys have any hints about that, it would be much appreciated!
The once grove of splendor,
Aforetime crowned by lilac and lily,
Lay now forevermore slender;
And all winds that liven
Silhouette a lone existence;
A leafless oak grasping at eternity.


"They say that I must learn to kill before I can feel safe, but I rather kill myself then turn into their slave."
- The Rasmus