Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Polidoro
Jan 5, 2011


Huevo se dice argidia. Argidia!
So, something weird is happening to a program I wrote and can't seem to figure it out. The program is a server that accepts connections on a socket and creates a new thread (pthread) to handle it. The code looks something like this:

C code:
while(true){
	pthread_t http_thread;
	int fd = accept(sock);
	pthread_create(http_thread,http_handler,&fd);
	pthread_detach(http_thread);
}
The thing is, when several connection attempts happen in quick succession the threads start doing some weird poo poo, I end up having several threads receiving the same value for fd, so some threads try to read from the same socket and some connections are never handled (because the fd value is lost somewhere). The problem disappears if I add a usleep() at the end of the while loop.

I assume creating a thread is too complex of an operation and it takes time to initialize the values passed to the new thread, so when it's time to initialize the values they've already changed somehow (because of a new connection).

Is my assumption correct? I know I shouldn't use the threads like that, and that the correct way is to use a thread pool. I was asked to do it this way.

edit: should point out this is not for work, it's for a networking class I'm taking.

Polidoro fucked around with this message at 04:41 on Sep 17, 2012

Adbot
ADBOT LOVES YOU

OddObserver
Apr 3, 2009
That'd likely be because you're passing in a pointer to a local to the thread start function. Don't do that --- by the time the thread is running, the variable may already be out of scope, with its stack space used for something else (like the instance of FD of the next iteration).

Polidoro
Jan 5, 2011


Huevo se dice argidia. Argidia!
poo poo, never thought about that. Thank you.

Diametunim
Oct 26, 2010
I think I'm just about finished.

code:
#include <stdio.h>
#include <math.h>


int main()
{
    float a, b, c, root1, root2, real, dis, complex, solchk; //Used for A,B,C inputs and the discrim
    char more = 'y';
    
    while(more == 'y' || more == 'Y')
    {
    printf("\n\t\tSolve quadritic equation for giving A, B, C coefficient");
    printf("\n\tPlease input A: ");
    scanf("%g", &a);
    printf("\n\tPlease input B: ");
    scanf("%g", &b);
    printf("\n\tPlease input C: ");
    scanf("%g", &c);
      
     dis = ((b*b) - (4*a*c));
     root1 = (-b + sqrt(b*b - 4*a*c)) / (2*a);
     root2 = (-b - sqrt(b*b - 4*a*c)) / (2*a);
     real = -b / (2*a);
     complex = sqrt(dis * -1)/(2*a);

     if (dis < 0)
     {
        printf("\n The first Root Value %g", real);
        printf("%6.3g", complex);     
     }
     else if (a == 0 && b != 0 && c != 0)
     {
          printf("\n Single Root, X = %g", -c/b);
     }
     else if (a == 0 && b == 0 && c == 0)
     {
          printf("\nInfinite Solutions");
     }
     else if (a == 0 && b == 0 && c != 0)
     {
        printf("\nContradict Equation");
     }
     else if (dis > 0)
     {
        printf("\nThe first root value = %g ", root1);
        printf("\nThe second root value = %g", root2);       
     }
     else if (dis == 0)
     {
         printf("\nRepeated root, X = %g", real);    
     }
      
    printf("\nDo more? (Y/N):");
    scanf("%s", &more);
     
    }
 
}
Anyone have any advice or improvements I could make? Sorry for my formatting by the way. I'm used to Eclipse doing the formatting for me when I was doing Java work. I realize this poo poo looks downright horrendous.

Thanks for the help everyone.

E: I should mention I know I'm missing a few outputs here and there. I just need to go back and add those in.

opt
Oct 10, 2007
So I'm doing some graph stuff in c for my algorithms class, I wrote my program on my mac and it works perfect (finds the square of a graph and outputs the list), so when I go and try and run it on the CS dept server, it gives me some crazy output:

code:
1: 2 -1250365176 4 3
2: 1 -1250365736
3: 2 -1250365736 1 5 4
4: 5 -1250365736 2 2
5: 4 -1250365736 2
On my mac is looks like :
code:
1: 2 4 3 5
2: 1 5
3: 2 1 5 4
4: 5 2 3
5: 4 2
I tried changing the ints to longs but it does the same thing just the numbers are big positive numbers instead and just some of the numbers being wrong, I'm guessing this has something to do with the different platforms but have no idea how to fix it, any suggestions?

Edit: Printing my original set of points comes out normal, printing everything as it goes into my linked lists looks the same, it just does this crazy output when I'm reading from the linked lists and printing it out. It is always the second part of the linked list too...once again, this works perfectly on my mac, I am completely at a loss.

opt fucked around with this message at 07:03 on Sep 17, 2012

Qwertycoatl
Dec 31, 2008

opt posted:

Edit: Printing my original set of points comes out normal, printing everything as it goes into my linked lists looks the same, it just does this crazy output when I'm reading from the linked lists and printing it out. It is always the second part of the linked list too...once again, this works perfectly on my mac, I am completely at a loss.

It's impossible to know because you didn't actually post the code, but could it be that when you print out the data at the end, the memory for it has already been freed?

opt
Oct 10, 2007
Removed: I figured it out finally, apparently my mac doesn't care if I don't set initial values for the first nodes of my linked list, but the server did, good learning experience at least.

opt fucked around with this message at 15:15 on Sep 17, 2012

X-BUM-RAIDER-X
May 7, 2008

opt posted:

Removed: I figured it out finally, apparently my mac doesn't care if I don't set initial values for the first nodes of my linked list, but the server did, good learning experience at least.

If you post the code, someone here might be able to explain why that is and give you advice to help avoid the same problem in the future.

LuciferMorningstar
Aug 12, 2012

VIDEO GAME MODIFICATION IS TOTALLY THE SAME THING AS A FEMALE'S BODY AND CLONING SAID MODIFICATION IS EXACTLY THE SAME AS RAPE, GUYS!!!!!!!
I've got a question regarding, I think, constructors and ADTs. I've got a mostly-functional program that I've almost completed, but I can't figure out how to solve one problem.

The program works with triangles and computes stuff like the angle of each corner and the area, based on provided values for each side of the triangle. A specification is that there be at least two constructors. One constructor handles the case where there is no input for any of the sides, while the other handles the case where there is input for all three sides. I have, consequently, set up the following in order to handle this:

From triangle.h
code:
class Triangle
{
...
public:
	Triangle();
	Triangle(double x, double y, double z);
...
};
From triangle.cpp
code:
Triangle::Triangle()
{
	//sets values to a default of (6,6,6) and then performs calculations
}

Triangle::Triangle(double x, double y, double z)
{
	//takes input values and performs calculations
}
Then, in my main.cpp, I try to set up a triangle to work with. If I have...

code:
Triangle tri(3,3,3);
tri.get_data();
...then everything works as expected (the second constructor is called) and the terminal reads out all the data I want. If I have...

code:
Triangle ();
...then the first constructor is called, but the data is inaccessible. I have no idea what is going on here and didn't even expect this to work, but it does, so... And then I have the case(s) that really confuses me:

code:
Triangle tri();
This compiles and runs, but doesn't use either constructor. If I attempt to use the get_data function (in just about any reasonable way imaginable), the program fails to compile.

I have been under the impression that the appropriate constructor will be called based upon what data is passed into the function because of overloading. This is the implementation I have been led to believe will work. What am I doing wrong?

Cat Plus Plus
Apr 8, 2011

:frogc00l:
This is most vexing parse problem. Basically, Triangle tri(); declares a function tri that returns a Triangle, not a variable. Use Triangle tri; instead.

Triangle() creates and yields an object, just like Triangle(3, 3, 3) would do (so you can do e.g. tri = Triangle(); later on).

Also, use constructor initialisation list. And this case really doesn't need two constructors, but that's probably coursework so I'm not surprised that it's dumb.

LuciferMorningstar
Aug 12, 2012

VIDEO GAME MODIFICATION IS TOTALLY THE SAME THING AS A FEMALE'S BODY AND CLONING SAID MODIFICATION IS EXACTLY THE SAME AS RAPE, GUYS!!!!!!!

quote:

This is most vexing parse problem. Basically, Triangle tri(); declares a function tri that returns a Triangle, not a variable. Use Triangle tri; instead.

I'm please to report that this works. Thank you. It makes sense that you've now explained it.

raminasi
Jan 25, 2005

a last drink with no ice
I have a best practices question.

Say I've got some long-running function, and I want users of the function to be able to get progress updates, so I have it take some kind of progress callback:
C code:
return_t long_operation(struct parameters params, void (*something_happened)(struct happening_payload));
Now if struct happening_payload has any kind of dynamically allocated fields I need to deal with who's responsible for freeing those resources. I can see two options:
-Provide a release_happening_payload function which does whatever releasing needs to be done, or
-Say that when the callback is done, the payload will be released by long_operation, so callers will have to copy whatever they need out.

I'm leaning toward option two because it makes the interface cleaner, but if I've not thought of something I'd love to hear it.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
From my understanding, you're worried about callbacks that store some data from happening_payload, and then getting a use-after-free error if the long operation completes?

If long_operation allocates struct happening_payload and everything inside it, then it owns the memory. Put some mention that happening_payload and all memory inside is invalid after the callback is called, and that you need to copy (or ref, if you have that) all data inside the struct.

raminasi
Jan 25, 2005

a last drink with no ice
So option 2. Thanks!

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Does C mandate structure alignment? That is, will a structure definition be guaranteed to compile to the same ABI across all compilers with any number of flags, given the same target architecture?

shrughes
Oct 11, 2008

(call/cc call/cc)

Suspicious Dish posted:

Does C mandate structure alignment? That is, will a structure definition be guaranteed to compile to the same ABI across all compilers with any number of flags, given the same target architecture?

No.

(For example, will int be 32 bits or 64 bits (or 16)? Will long be 32 bits or 64 bits? Will the alignment of double be 4 or 8? Will the alignment of long double be 4 or 8 or 16? Different OSes and different compilers believe differently. You can't even guarantee size so good luck guaranteeing structure alignment. And practically speaking, in the wild, you'll see different structure alignment rules. Particularly for doubles being 4 or 8 byte aligned on x86.

shrughes fucked around with this message at 09:27 on Sep 20, 2012

X-BUM-RAIDER-X
May 7, 2008

Suspicious Dish posted:

Does C mandate structure alignment? That is, will a structure definition be guaranteed to compile to the same ABI across all compilers with any number of flags, given the same target architecture?

Assuming your compiler supports it (most do), #pragma pack(1) will guarantee that your structure is 1-byte aligned. However like the above poster mentioned, the size of the datatypes may differ between compilers and architectures as the C standard doesn't specify a maximum size for primitives, only a minimum.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I was assuming the same architecture and OS, but with msvc vs. gcc vs. icc vs. clang vs. suncc or whatever.

Does that mean that if I'm using a closed-source library that ships public structs in their header files as part of their API, I just have to pray to the gods that their compiler's structure alignment matches with mine?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
There is a more-nebulous-than-you-might-think concept called the "target platform" which compilers generally respect. Compilers for the same target platform are generally supposed to produce compatible code, at least on the C level. So as long as it's actually compiled for the platform you're going to use it on, you should be fine.

To describe the target platform, GCC hath bequeathed upon the world the idea of a "target triple", a combination of the architecture, vendor, operating system, and optionally the environment. So, for example, i386-pc-linux-gnu is a different platform from i386-pc-mingw32 and i386-apple-darwin, and all of those do, in fact, have slightly different ABI rules.

Salsa McManus
Jul 12, 2007

Khezu Khezu Khezu Khezu Khezu Khezu Khezu Khezu
Found out I'm absolutely terrible at C++ a few weeks into this Intro to C++ class at the local community college. Hope you cool cats don't mind me bugging you with plebeian level poo poo.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

rjmccall posted:

There is a more-nebulous-than-you-might-think concept called the "target platform" which compilers generally respect. Compilers for the same target platform are generally supposed to produce compatible code, at least on the C level. So as long as it's actually compiled for the platform you're going to use it on, you should be fine.

To describe the target platform, GCC hath bequeathed upon the world the idea of a "target triple", a combination of the architecture, vendor, operating system, and optionally the environment. So, for example, i386-pc-linux-gnu is a different platform from i386-pc-mingw32 and i386-apple-darwin, and all of those do, in fact, have slightly different ABI rules.

Is there a standard set of rules for each "target platform" listed anywhere, in the gcc documentation or otherwise? Or is it "let's study the output that gcc gives, and then try to match it". Just curious here, seems like it would be interesting to read.

But thanks for explaining; it certainly squashes a few ideas in my head.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Suspicious Dish posted:

Is there a standard set of rules for each "target platform" listed anywhere, in the gcc documentation or otherwise? Or is it "let's study the output that gcc gives, and then try to match it". Just curious here, seems like it would be interesting to read.

In theory there's an obvious platform vendor who's responsible for documenting this; for example, here is the Apple documentation (which despite the name also includes fundamental type information). Usually the ABI comes from the architecture vendor; OS vendors then tweak that (or totally ignore it and do their own thing). Architecture vendors tend to only barely understand C, so a lot of things go answered — my perennial favorite is "what exactly is the guaranteed range of a stored, passed, or returned value of _Bool?". In the Unix world, there's also usually a delightful uncertainty about which things, exactly, still apply from the System V ABI. Oh, and there's a habit that I've never understood of putting massive header dumps in the ABI document — and not for basic C things, but for libraries like X11.

pseudorandom name
May 6, 2007

There's also charming things like the i386 psABI having never been updated since its creation, so things like SSE and AVX are basically specified as "whatever gcc does"

Contero
Mar 28, 2004

Anyone know of a good library for representing sets with ranges where you can do intersections, unions and differences?

For example I'd like to be able to do operations like this (pseudocode):

code:
Set a = {0..255};
Set b = {25..50, 2000};

Set c = union(a, b); // {0..255, 2000}
Set d = intersect(a, b); // {25..50}
Set e = difference(a, b); // {0..24, 51..255}
For once I don't actually feel like implementing a basic data structure from scratch.

raminasi
Jan 25, 2005

a last drink with no ice
e: misread the question

That Turkey Story
Mar 30, 2003

Contero posted:

Anyone know of a good library for representing sets with ranges where you can do intersections, unions and differences?

For example I'd like to be able to do operations like this (pseudocode):

code:
Set a = {0..255};
Set b = {25..50, 2000};

Set c = union(a, b); // {0..255, 2000}
Set d = intersect(a, b); // {25..50}
Set e = difference(a, b); // {0..24, 51..255}
For once I don't actually feel like implementing a basic data structure from scratch.

I haven't personally used it, but the Boost Interval Container Library should be able to do everything that you need.

an skeleton
Apr 23, 2012

scowls @ u
So I'm writing a little customer class for homework, and I'm wondering if this is okay to use as a constructor:
code:
customer::customer(void)
{
	char mail; bool done=false;
	do{
	cout<<"Would this person like to be on the mailing list? (Y/N)"<<endl;
	cin>>mail;
	if(mail=='Y'||mail=='y'){
		mailingList=true;
		done=true;}
	else if(mail=='N'||mail=='n'){
		mailingList=false;
		bool done=true;
	}
	else
		done=false;
	}while(done==false);
}
and also, I was wondering if that was formatted OK, and if not what is wrong?

raminasi
Jan 25, 2005

a last drink with no ice
The constructor should just be
code:
customer::customer(bool onMailingList) : mailingList(onMailingList) { }
(Whether it's all on one line or not is a question of style.)

If you haven't covered initializer lists yet:
code:
customer::customer(bool onMailingList) {
    mailingList = onMailingList
}
Each function should do basically one thing, so the customer constructor should be constructing customers, and that's it. Figuring out whether Bob Hope wants to be on a mailing list or whatever should happen somewhere else.

I can't help but notice that your customers don't actually have any information stored about them in their constructor other than their mailing list status. Were you just trying to prune down your example, or are there some larger questions about class design here?

Boz0r
Sep 7, 2006
The Rocketship in action.
I've got a Visual Studio question. I've been given some code by our instructor with some sub-directories and I can't get the include-statements to work properly. He uses Linux where it works perfectly.

stuff like this:

math/f3.c
code:
#include  <math/f3.h>
complains that the file doesn't exist.

And I've got a couple of these all with the samme errors.

How should I write it for it to work?

I'm not really familiar with VS, I normally write Java.

Cat Plus Plus
Apr 8, 2011

:frogc00l:

an skeleton posted:

and also, I was wondering if that was formatted OK, and if not what is wrong?

done == false should be !done. As GrumpyDoctor said, don't put I/O logic in constructors. Closing braces are usually put on the new line, it's more readable this way:

C++ code:
if (xxx) {
   // ...
} else {
   // ...
}
Also, bool done = false; inside your else if branch defines new variable which overshadows the one you want to change. The body of the loop should be indented:

C++ code:
do {
    // ...
} while (xxx);

Boz0r posted:

How should I write it for it to work?

Open project settings and adjust include directories (under C/C++ Preprocessor or something like that) to include the one with math subdirectory. E.g. if that header lives in C:\foo\math\f3.h, add C:\foo as the include directory.

nielsm
Jun 1, 2009



Apart from what everyone else has said...

an skeleton posted:

code:
customer::customer(void)
This is a C-ism. In C++ you don't put (void) to denote an empty parameter list, you just put (). Your compiler should also be giving you a warning about that. (If not, enable warnings!)
(In C, () in a function declaration means "undeclared parameter list" while in C++ it means "empty parameter list".)

yippee cahier
Mar 28, 2005

Boz0r posted:

I've got a Visual Studio question. I've been given some code by our instructor with some sub-directories and I can't get the include-statements to work properly. He uses Linux where it works perfectly.

stuff like this:

math/f3.c
code:
#include  <math/f3.h>
complains that the file doesn't exist.

And I've got a couple of these all with the samme errors.

How should I write it for it to work?

I'm not really familiar with VS, I normally write Java.

First, you should use quotations for non-system header paths:
code:
#include  "math/f3.h"
Make sure your project root directory is the parent of the "math" directory and the "additional includes" path in VS is pointing there as well.

b0lt
Apr 29, 2005

GrumpyDoctor posted:

The constructor should just be
code:
customer::customer(bool onMailingList) : mailingList(onMailingList) { }
(Whether it's all on one line or not is a question of style.)

If you haven't covered initializer lists yet:
code:
customer::customer(bool onMailingList) {
    mailingList = onMailingList
}
Each function should do basically one thing, so the customer constructor should be constructing customers, and that's it. Figuring out whether Bob Hope wants to be on a mailing list or whatever should happen somewhere else.

I can't help but notice that your customers don't actually have any information stored about them in their constructor other than their mailing list status. Were you just trying to prune down your example, or are there some larger questions about class design here?

customer::customer(bool onMailingList) should be explicit customer::customer(bool onMailingList) to prevent implicit conversion.

raminasi
Jan 25, 2005

a last drink with no ice

b0lt posted:

customer::customer(bool onMailingList) should be explicit customer::customer(bool onMailingList) to prevent implicit conversion.

Yup, totally forgot about that. Welcome to C++!

an skeleton
Apr 23, 2012

scowls @ u

GrumpyDoctor posted:

The constructor should just be
code:
customer::customer(bool onMailingList) : mailingList(onMailingList) { }
(Whether it's all on one line or not is a question of style.)

If you haven't covered initializer lists yet:
code:
customer::customer(bool onMailingList) {
    mailingList = onMailingList
}
Each function should do basically one thing, so the customer constructor should be constructing customers, and that's it. Figuring out whether Bob Hope wants to be on a mailing list or whatever should happen somewhere else.

I can't help but notice that your customers don't actually have any information stored about them in their constructor other than their mailing list status. Were you just trying to prune down your example, or are there some larger questions about class design here?

They are 'extending' a class called "Person." Thanks to all, and to the person who said "void" was not supposed to be in the parameters, that was put there by default by Visual Studio for whatever reason.

One more question, why is Visual Studio not letting me initialize the Person or customer class in the main? It's been a while since I messed around with classes, but I don't remember having to do anything particularly special to get the main to recognize that those classes exist, other than having the '.cpp' and '.h' files in the same folder as the project?

Cat Plus Plus
Apr 8, 2011

:frogc00l:

an skeleton posted:

One more question, why is Visual Studio not letting me initialize the Person or customer class in the main?

Post the code and errors. Did you include the header?

an skeleton
Apr 23, 2012

scowls @ u

PiotrLegnica posted:

Post the code and errors. Did you include the header?

code:
#include <iostream>
#include <iomanip>

using namespace std;

void main(){

Person test;
customer test2;

}
here it is, it's probably some silly mistake but there are red lines under the Person/customer indicating that they aren't recognized by the compiler.

nielsm
Jun 1, 2009



an skeleton posted:

code:
#include <iostream>
#include <iomanip>

using namespace std;

void main(){

Person test;
customer test2;

}
here it is, it's probably some silly mistake but there are red lines under the Person/customer indicating that they aren't recognized by the compiler.

Nothing in that declares the Person class. You need to include your header that declares the class.

Cat Plus Plus
Apr 8, 2011

:frogc00l:

an skeleton posted:

here it is, it's probably some silly mistake but there are red lines under the Person/customer indicating that they aren't recognized by the compiler.

You didn't include the header. Add #include "Person.hpp" and #include "customer.hpp" or however you called them.

Adbot
ADBOT LOVES YOU

an skeleton
Apr 23, 2012

scowls @ u
I added
code:
#include "customer.h"
#include "Person.h"
and now it works, but I swear that I tried that before and it didn't work. Oh well, thanks a lot!

One more question: I want each customer to have it's own number assigned, custNum, that it gets when it is created. I tried making a totalCust global variable in the main that is 0, but I guess the customer class doesn't have access to that.

an skeleton fucked around with this message at 00:03 on Sep 25, 2012

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply