Jump to content

Segmentation fault (cd) but only inside a class.

¨TrisT¨
Go to solution Solved by fizzlesticks,
19 minutes ago, ¨TrisT¨ said:

Tell me if you have a better way to do it or I'm missing something very obvious.

And thank you.

You can use a char[] instead of char* to avoid the new and delete.

 

char buffer[31];
time_t now = time(0);
tm* timeinfo = gmtime(&now);
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %X UTC", timeinfo);
return std::string(buffer);

 

Hi!

Here's the code (excuse any errors, copying the code from VM cuz clipboard sharing just won't work ever):

#include <iostream>
#include <ctime>

using namespace std;

class TestClass {
  public:
    static void htdtp();
};

void TestClass::htdtp(){
  time_t now;
  now = time(0);
  char* buffer;
  tm* timeinfo;
  timeinfo = gmtime(&rawtime);
  strftime (buffer, 80, "%a, %b %Y %X %Z", timeinfo);
  cout << buffer;
}

int main(){
  TestClass::htdtp();
}

The idea is to return, I've tried doing so and changing stuff around, and this is the point at which I gave up because it just keeps giving me the same error.

 

This prints out "Segmentation fault (core dumped)" and I can't understand why, because when you put the exact same code that's inside htdtp in main and execute it, it works wonders.

 

Why is this happening? Isn't a segmentation fault error supposed to be associated with ilegal memory usage? If everything is declared and uses exclusively inside the function how can that happen?

 

Thank you.

Link to comment
Share on other sites

Link to post
Share on other sites

I'd recommend you use a debugger (like GDB), or if you're lazy, just throw in a few print statements to see exactly where it is segfaulting. 

 

It's very useful to try and figure out what line causes the issue and then think about why that line is problematic. 

PSU Tier List | CoC

Gaming Build | FreeNAS Server

Spoiler

i5-4690k || Seidon 240m || GTX780 ACX || MSI Z97s SLI Plus || 8GB 2400mhz || 250GB 840 Evo || 1TB WD Blue || H440 (Black/Blue) || Windows 10 Pro || Dell P2414H & BenQ XL2411Z || Ducky Shine Mini || Logitech G502 Proteus Core

Spoiler

FreeNAS 9.3 - Stable || Xeon E3 1230v2 || Supermicro X9SCM-F || 32GB Crucial ECC DDR3 || 3x4TB WD Red (JBOD) || SYBA SI-PEX40064 sata controller || Corsair CX500m || NZXT Source 210.

Link to comment
Share on other sites

Link to post
Share on other sites

11 minutes ago, djdwosk97 said:

I'd recommend you use a debugger (like GDB), or if you're lazy, just throw in a few print statements to see exactly where it is segfaulting. 

Okay I solved it?

I swapped

char* buffer;

for

char buffer[31];

I never quite understood what char* or char varname[] do.

I understand they're the same, but if you don't declare them or indicate their length, are they just gonna be an unlimited hole in memory to put things in?

I figure the things strftime was trying to put into the buffer were too much and it was trying to use space that didn't belong to it.

Is it "dangerous" to not declare the 'char*'s? I mean shouldn't it be completely pointless not to do so if there's always the danger of whatever you're putting in there not fitting?

Link to comment
Share on other sites

Link to post
Share on other sites

11 minutes ago, ¨TrisT¨ said:

Okay I solved it?

I swapped


char* buffer;

for

char buffer[31];

I never quite understood what char* or char varname[] do.

I understand they're the same, but if you don't declare them or indicate their length, are they just gonna be an unlimited hole in memory to put things in?

I figure the things strftime was trying to put into the buffer were too much and it was trying to use space that didn't belong to it.

Is it "dangerous" to not declare the 'char*'s? I mean shouldn't it be completely pointless not to do so if there's always the danger of whatever you're putting in there not fitting?

Aren't pointers fun? Char* creates a pointer to a string of chars whereas char buffer[31] creates space for 31 char's. If you wanted to use char* buffer instead, you would need to change your call to strfrtime() to: 


strftime (&buffer, 80, "%a, %b %Y %X %Z", timeinfo);

 

Well, buffer overflow is an issue (and that's why you wouldn't want to do char buffer[31] because that could overflow since it's a fixed length). If you use char *, then you don't have to worry about an overflow since strfrtime() creates enough space to accomodate the string that's going to be copied into it. At least that's how gets()/getline() handle things, I'm not sure if strfrtime() works the same way. 

PSU Tier List | CoC

Gaming Build | FreeNAS Server

Spoiler

i5-4690k || Seidon 240m || GTX780 ACX || MSI Z97s SLI Plus || 8GB 2400mhz || 250GB 840 Evo || 1TB WD Blue || H440 (Black/Blue) || Windows 10 Pro || Dell P2414H & BenQ XL2411Z || Ducky Shine Mini || Logitech G502 Proteus Core

Spoiler

FreeNAS 9.3 - Stable || Xeon E3 1230v2 || Supermicro X9SCM-F || 32GB Crucial ECC DDR3 || 3x4TB WD Red (JBOD) || SYBA SI-PEX40064 sata controller || Corsair CX500m || NZXT Source 210.

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, djdwosk97 said:

Aren't pointers fun? Char* creates a pointer to a string of chars whereas char buffer[31] creates space for 31 char's. If you wanted to use char* buffer instead, you would need to change your call to strfrtime() to: 


strftime (&buffer, 80, "%a, %b %Y %X %Z", timeinfo);

 

Well, buffer overflow is an issue (and that's why you wouldn't want to do char buffer[31] because that could overflow since it's a fixed length). If you use char *, then you don't have to worry about an overflow since strfrtime() creates enough space to accomodate the string that's going to be copied into it. At least that's how gets()/getline() handle things, I'm not sure if strfrtime() works the same way. 

I actually find it sort of interesting, you get to understand how things work.

This outputs the date and time formatted for an http response, the length of it won't ever be greater than 30 characters so no problem there.

And actually when you say pointer to a string, it's actually just a non-size-disclosed array of chars that is null-terminated.

I don't know how much space c++ allocates for a char* or whether and therefore how it even does it, but it seems that inside a class, for some reason the job isn't well done.

Maybe it's just a bug because when I set the buffer size to 10 it gives me a "stack smashing detected \n Aborted (core dumped)" error. Maybe some bug that makes it try to write to some other arbitrary space wherever?

 

char* + strftime 80 is what was giving me the segmentation fault in the first place, then again, it was completely fine outside the class.

Link to comment
Share on other sites

Link to post
Share on other sites

45 minutes ago, ¨TrisT¨ said:

I never quite understood what char* or char varname[] do.

I understand they're the same

They're not the same, someone explained the differences in your last thread.

Quote

Well, buffer overflow is an issue (and that's why you wouldn't want to do char buffer[31] because that could overflow since it's a fixed length).

Both char* and char[] have the same overflow problems. When you pass a char[] to a function it decays into a char*. That's why the function has a parameter for your buffer size.

 

22 minutes ago, ¨TrisT¨ said:

This outputs the date and time formatted for an http response, the length of it won't ever be greater than 30 characters so no problem there.

The second parameter to strftime is the max length your buffer. If you're only making a buffer 30 characters long you should pass 30, not 80.

24 minutes ago, ¨TrisT¨ said:

I don't know how much space c++ allocates for a char* or whether and therefore how it even does it, but it seems that inside a class, for some reason the job isn't well done.

If you just do "char* c;" c++ doesn't allocate any space for your string and trying to write to *c will give the errors and crashes you've seen. If you want to use a char* instead of a char[] for your buffer you will need to allocate space with new then delete it yourself.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, fizzlesticks said:

They're not the same, someone explained the differences in your last thread.

Both char* and char[] have the same overflow problems. When you pass a char[] to a function it decays into a char*. That's why the function has a parameter for your buffer size.

 

The second parameter to strftime is the max length your buffer. If you're only making a buffer 30 characters long you should pass 30, not 80.

If you just do "char* c;" c++ doesn't allocate any space for your string and trying to write to *c will give the errors and crashes you've seen. If you want to use a char* instead of a char[] for your buffer you will need to allocate space with new then delete it yourself.

I'm such an asshole, I'm greedy, and I read a page on pointers on my phone when I was out, so when I understood it, I just came back, started coding and "I'll read it in a minute" 'd that thread for 5 hours.

I've read it now, and across my searches I found this that actually really made a lot of stuff click into place:

 char a[] = "hello";  // array

   +---+---+---+---+---+---+
a: | h | e | l | l | o |\0 |
   +---+---+---+---+---+---+

 char *p = "world"; // pointer

   +-----+     +---+---+---+---+---+---+
p: |  *======> | w | o | r | l | d |\0 |
   +-----+     +---+---+---+---+---+---+

By Timothy Jones here http://stackoverflow.com/questions/9627962/is-it-possible-to-convert-char-to-char-in-c

 

Now, I've been looking at what can be done, one can't return a char array because you can't have a char array function.

I did read something on being able to return it on a void function through the argument, but that's not what I'm after.

I also couldn't return the char* created with new because I had no sure way to know it would get deleted, given the ending of the function won't make that happen.

char* alone straight up doesn't work because of previously explained reasons.

Using a char array and converting it to a char* also won't work because the conversion always must involve memory allocation for the char*, memory which will have to be manually freed, which, then again I have no sure way of knowing will happen after I return.

So the only practical solution I ended up finding was just a string.

Create a char* with new, create a string from it, delete it and return the string.

Code:

char* buffer = new char[31];
time_t now = time(0);
tm* timeinfo = gmtime(&rawtime);
strftime(buffer, 31, "%a, %d %b %Y %X UTC", timeinfo);
std::string str(buffer);
delete[] buffer;
return str

 

Tell me if you have a better way to do it or I'm missing something very obvious.

And thank you.

Link to comment
Share on other sites

Link to post
Share on other sites

19 minutes ago, ¨TrisT¨ said:

Tell me if you have a better way to do it or I'm missing something very obvious.

And thank you.

You can use a char[] instead of char* to avoid the new and delete.

 

char buffer[31];
time_t now = time(0);
tm* timeinfo = gmtime(&now);
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %X UTC", timeinfo);
return std::string(buffer);

 

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, fizzlesticks said:

You can use a char[] instead of char* to avoid the new and delete.

 


char buffer[31];
time_t now = time(0);
tm* timeinfo = gmtime(&now);
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %X UTC", timeinfo);
return std::string(buffer);

 

That's a final then I guess.

Thank you sir :D

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×